realloc()、malloc()、calloc()的用法

realloc()

原型:extern void *realloc(void *mem_address,
unsigned int newsize);

语法:指针名 =(数据类型 * )realloc(要改变内存大小的指针名,新的大小);
ps:(新的大小可大可小(如果新的大小大于原内存大小,则新分配部分不会被初始化;如果新的大小小于原内存大小,可能会导致数据丢失)

头文件:#include <stdlib.h> ,有些编译器需要#include <malloc.h>,在 TC2.0中可以使用alloc.h头文件。

功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

ps:内存分配具体情况:1.如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address。这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。那么就ok。得到的是一块连续的内存。
2.如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。老块被放回堆上。
如果原有内存后面没有足够空间将原有空间扩展成一个连续的新大小的话,realloc函数就会以第二种方式分配内存,此时数据发生了移动,那么所记录的原来的内存地址q所指向的内存空间实际上已经放回到堆上了!这样就会产生q指针的指针悬挂,即指针指向了一块没有分配给用户使用的内存,如果再用q指针进行操作就可能发生意想不到的问题。所以在应用realloc函数是应当格外注意这种情况。

返回类型:返回的是一个void类型的指针:调用成功。(这就要 求在你需要的时候进行强制类型转换)(如果mem_address为NULL,则realloc()和malloc()类似。分配一个newsize的内存块,返回一个指向该内存块的指针。)
返回NULL:当需要扩展的大小(第二个参数)为0并且 第一个参数不为NULL时。此时原内存变成“free(游离)”的了。
返回NULL:当没有足够的空间可供扩展的时候(扩大原来的内存块或者分配新的内存块)。此时,原内存空间的大小维持不变。

注意:a.当内存不再使用时,应使用free()函数将内存块释放。
realloc失败的时候,原来的内存不改变,不会释放也不会移动。
b.假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址; 假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址
c.如果size为0,效果等同于free()。这里需要注意的是只对指针本身进行释放,例如对二维指针**a,对a调用realloc时只会释放一维,使用时谨防内存泄露。
d.传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的。
e.传递给realloc的指针可以为空,等同于malloc。
https://baike.baidu.com/item/realloc/659993.

malloc()

原型:void *malloc(unsigned int size);
ps:size仅仅为申请内存字节大小,与申请内存块中存储的数据类型无关,故编程时建议通过以下方式给出,“长度 * sizeof(数据类型)”;

头文件:stdlib.h

返回类型 :如果分配成功,此函数的返回值是分配区域的起始地址,或者说,此函数是一个指针型函数,返回的指针指向该分配域的开头位置。返回为void型指针,因此必要时要进行类型转换。它能向系统申请分配一个长度为num_bytes(或size)个字节的内存块。作用是在内存的动态存储区中分配一个长度为size的连续空间。如果分配不成功,返回空指针NULL。

当内存不再使用时,应使用free()函数将内存块释放(free函数能释放某个动态分配的地址,表明不再使用这块动态分配的内存了,实现把之前动态申请的内存返还给系统)。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。

ps:与new的区别:new则不然,是c++的关键字,它本身不是函数。new不依赖于头文件。在使用上,malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。
https://baike.baidu.com/item/malloc%E5%87%BD%E6%95%B0/8582146.

calloc()

原型:void* calloc(unsigned int num,unsigned int size);
ps:num:对象个数,size:对象占据的内存字节数,相较于malloc函数,calloc函数会自动将内存初始化为0,而malloc不做初始化,分配到的空间中的数据是随机数据。

头文件:stdlib.h或malloc.h

返回类型:在内存的动态存储区中分配num个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
ps:因为calloc()函数会清空分配的内存,而malloc()函数不会,所以可以调用以“1”作为第一个实参的calloc()函数,为任何类型的数据项分配空间。比如:
struct point{ int x, y;} *pi;
pi = calloc(1, sizeof(struct point));
在执行此语句后,pi将指向一个结构体,且此结构体的成员x和y都会被设为0。
一般使用后要使用 free(起始地址的指针) 对内存进行释放,不然内存申请过多会影响计算机的性能,以至于得重启电脑。如果使用过后不清零,还可以使用该指针对该块内存进行访问。
https://baike.baidu.com/item/calloc.

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务