动态开辟内存总结

动态开辟内存是在程序执行过程中进行开辟空间的,主要在堆,栈中开辟 

有关堆中动态开辟内存空间的函数有malloc,calloc,realloc,free。栈中开辟空间的有alloca。

   void *malloc( size_t size );

   void *calloc( size_t num, size_t size );

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

   void free( void *memblock );

   void *_alloca( size_t size );

size_t为无符号整型,在进行申请时要注意其值的范围,防止其整型溢出而带来的误差(例如申请一个3,4GB的空间失败,但是比这更大的空间或许能成功,主要在于整型溢出使其值变小)。

 

calloc与malloc区别在于其参数形式不同,还有其申请后的未初始值不同。calloc是利用malloc函数申请内存空间后,再从头至尾置零,所以其时间花费多一点,但是在空间里填充字符串时可不用再关注字符串结束符了。

 

malloc函数申请的size是以字节为单位的,为了能够提高可移植性,使用  sizeof(类型)*数目  来进行申请。如果申请成功则会返回一个void *地址,若是失败则会返回NULL,所以需要对该返回值进行判断。要利用申请到的空间需通过返回的地址进行操作,将返回的地址进行强制转化类型后才能开始使用。有关指针的操作,C对于其类型匹配十分的严格。开辟的空间是一段连续的内存空间,里面的值都是随机值。

 

在返回的地址前存在一个关于该空间的结构体,记录着该空间的申请信息,当要释放该空间时,以其返回的地址为基址,通过偏移一定长度的空间来找到该内存块的状态进行修改而释放。不能对已经修改过的头指针进行释放,进行备份,释放时使用原值,释放完毕,将该指针赋值NULL。

 

realloc函数用于修改一个原先已经分配的内存块大小,可以对该空间进行扩大或者压缩。特别注意在扩大内存时,定要接收其返回的地址,如果该内存块不够大时,操作系统会重新找到合适大小的内存块并将原先的内容拷贝到该内存中并返回新内存地址,释放原内存块。如果内存块足够,则会将新加的内存块添加到原先内存的后面,新内存未初始化时存储的是随机值,如果是缩小内存块,则内存块尾部的部分内存被系统回收,剩余部分内存的原先内容保留。

 

alloca函数是在栈中申请空间,申请之后的管理由系统操作,无需人工释放,随着函数的调用结束,它也自然消失,如同局部变量的一样。其弥补了C89版本前申请数组时,中括号内不能出现表达式变量,只能是常数的缺憾。

 

申请失败的原因有以下几点:1.内存空间不够。内存空间的大小由计算机的内存大小、其使用状况和操作系统限制等因素限制。2.堆被锁定,无法使用。3.操作系统不正常。

 

注意事项:1.不要访问已经被free函数释放了的内存(可以在释放内存后,将此指针赋值为NULL)。

          2.对NULL指针进行解引用操作,对分配的内存进行操作是越界,释放并非动态开辟的内存,释放一块动态分配的内存的一部分(对返回指针操作时进行了赋值,使其位置偏移),对一块动态内存释放之后被继续使用。

          3.free的参数要么是NULL,要么是调用alloc返回的值,向free传递一个NULL参数不起任何作用。

          4.当动态开辟的内存使用完毕后,及时释放,使其可以重新被分配使用。如果使用完毕不释放会造成内存泄漏。


malloc的底层使用的brk和mmap系统调用,malloc是libc函数库中的,其介于系统函数和库函数之间,是嵌入在编译器中的,linux下的编译器g++,gcc使用的是ptmalloc。也存在tcmaloc,jemalloc等等内存管理库。

new和malloc的区别:1>new是运算符可以重载,而malloc是库函数,new的底层使用的malloc。2>new申请空间不需要确定大小,只需要传入的是对象的数量,而malloc需要计算申请的内存大小。3>new 返回之后就是对象的类型,而malloc返回之后需要强制类型转化为所需要的类型。4>new申请空间之后调用了构造函数进行初始化对象。5>new调用的delete释放,而malloc调用free释放。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值