malloc,calloc,realloc,memset之间的关系

阅读下面文章可以同时参考C运行时库(C run-time library)
1.首先要了解的是:

  • 堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的
  • 堆区(heap):一般由程序员分配与释放,基程序员不释放,程序结束时可能由操作系统回收(C/C++没有此等回收机制,Java/C#有),注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
  • 全局区(静态区)(static):全局变量和静态变量的存储是放在一块儿的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
  • 文字常量区:常量字符串是放在这里的,程序结束后由系统释放。
  • 程序代码区:存放函数体的二进制代码。

2.malloc()可以从堆上获得指定字节的内存空间

void *malloc(
size_t size
);

(1)形参size为要求分配的字节数。
(2)如果函数执行成功,malloc返回获得内存空间的首地址;如果函数执行失败,那么返回值为NULL。
(3)由于 malloc函数值的类型为void型指针,因此,可以将其值类型转换后赋给任意类型指针,这样就可以通过操作该类型指针来操作从堆上获得的内存空间。
(4)malloc函数分配得到的内存空间是未初始化的。因此,一般在使用该内存空间时,要调用另一个函数memset来将其初始化为全0。

3.memset()将指定的内存空间按字节单位置为指定的字符

void *memset(
void *dest,
int c,
size_t count
);

该函数可以将指定的内存空间按字节单位置为指定的字符c。其中,dest为要清零的内存空间的首地址,c为要设定的值,count为被操作的内存空间的字节长度。如果要用memset清0,变量c实参要为0。

4.calloc函数的功能与malloc函数的功能相似,都是从堆分配内存

void *calloc(
size_t num,
size_t size
);

(1)calloc函数为数组分配存储空间num元素,每个长度size字节。 每个元素初始化为 0。
(2)calloc返回指向分配的空间的指针。 返回值指向的存储空间保证适当对齐任何类型的对象的存储。 若要获取指向一种类型的指针,而不是返回void,应使用类型转换。

5.realloc()可以实现内存分配和内存释放的功能

void *realloc(
void *memblock,
size_t size
);

(1)指针memblock必须为指向堆内存空间的指针,即由malloc函数、calloc函数或realloc函数分配空间的指针。
(2)realloc函数将指针 memblock指向的内存块的大小改变为size字节。如果size小于或等于memblock之前指向的空间大小,那么。保持原有状态不变。如果size大于原来memblock之前指向的空间大小,那么,系统将重新为memblock从堆上分配一块大小为size的内存空间,同时,将原来指向空间的内容依次复制到新的内存空间上,memblock之前指向的空间被释放。relloc函数分配的空间也是未初始化的。
???(3)realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;可如果数据后面的字节不够的话,问题就出来了,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上。

6.free()

void free(
void *memblock
);

(1)从堆上获得的内存空间在程序结束以后,系统不会将其自动释放,需要程序员来自己管理。一个程序结束时,必须保证所有从堆上获得的内存空间已被安全释放,否则,会导致内存泄露
(2)若释放了无效的指针(malloc/calloc/realloc的指针指向未分配的内存块),可能会影响后续分配请求,并导致错误


注意:

1.有经验的程序员更喜欢使用calloc(),因为这样的话新分配内存的内容就不会有什么问题,调用calloc()肯定会清0,并且可以避免调用memset().

2.进程对动态内存的请求被认为是不紧迫的。例如,当进程的可执行文件被装入时,进程并不一定立即对所有的代码进行访问。类似地,当进程调用malloc() 请求动态内存时,并不意味着进程很快就会访问所有获得的内存。因此一般来说,内核总是尽量推迟给用户态进程动态分配内存。

3.malloc()函数有一个参数,即分配的内存空间的大小,malloc在分配内存的时候会保留一定的空间用来记录分配情况,分配的次数越多,这些记录占用的空间就越多。另外,根据malloc实现策略的不同,malloc每次在分配的时候,可能分配的空间比实际要求的多些,多次分配会导致更多的这种浪费,当然,这些都跟malloc的实现有关;

4.relloc()可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或者缩小,原有内存中的内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。
relloc()并不保证调整后的内存空间和原来的内存空间保持同一内存地址,相反,relloc返回的指针很可能指向一个新地址。所以在代码中,我们必须将relloc的返回值,重新赋值给memblock : memblock =(size_t *) relloc (memblock ,sizeof(size_t )*15);

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值