初夏小谈:C&C++动态内存管理

一、C语言中的动态内存管理方式

malloc/calloc/realloc三种开辟内存的方式

    1.malloc函数原型  void* malloc(size_t size)

       需要动态开辟内存空间时调用malloc函数,可以在堆上开辟出一块连续的内存空间,并且返回指向这一块内存的指针。来满足程序的需求。

     1.2.在用malloc函数开辟空间时应注意:

  • 申请开辟空间成功,则会返回一个指向这块内存的指针
  • 如果申请开辟空间失败,就会返回一个NULL指针,所以malloc开辟的空间一定要检查是否开辟成功
  • 由于malloc的开辟空间返回值类型是void* 开辟的空间类型需要我们自己根据需要来给定。
  • 当size大小是0时开辟空间的大小是未定义行为,具体大小有编译器决定VS2017默认分配一个类型空间的大小

  2.C语言另外一个可以在堆上开辟空间的函数即calloc

     2.1函数原型:void* calloc(size_t Num, size_t size)

     2.2其中Num是块个数,size是一块所占字节大小

     2.3calloc函数就是为Num个大小为size的元素开辟一块空间

    calloc和malloc的区别就是:calloc在开辟空间后,会初始化空间的每个字节为0

  3.C语言中第三种realloc函数将更加灵活地开辟空间

     3.1realloc函数原型: void* realloc(void* ptr, size_t size)

     3.2 realloc开辟空间,当申请的空间大了或者小了都会及时作出调整出一块合适的空间。

     3.3ptr要调整的内存的地址的指针,size调整后的大小

     3.4返回值为调整后的返回内存空间的起始地址。在申请的空间大了时直接缩小空间即可,不用搬移数据。在申请空间小时往大的调整过程总有两种情况:①先查看原由空间后面的可用空间够不够,如果够,就不用搬移数据直接追加空间,②当后面空间不够时就需要重新开辟一块内存空间,再将数据搬移过去。

在开辟了堆上的内存之后一定要及时释放防止造成内存泄漏。

二、说完C语言中的动态开辟空间问题在说C++中的动态内存管理

  在C++中当然也可以通过C语言中的函数来进行动态内存管理,但有时会比较麻烦,所以C++有自己的动态管理内存的方式

  用new和delete操作符来申请和释放空间

 在C++中通过一个new来为对象开辟空间,它会调用构造函数初始化空间,通过delete释放空间前会调用析构函数进行对象中资源的清理工作。

  1new Object与delete Object

   在创建一个对象时会经历两步:

     第一步会在底层会先调用operator new来申请一块空间,之后再调用构造函数来对对象进行初始化。operator new申请空间有两种可能:①:一种是申请成功返回空间首地址,②:再就是申请失败,在申请失败时就需要用户来给出解决办法。如果用户给定解决办法。就会检测到显示提供,就循环申请空间,每次将占据内存且不使用的对象清理调,直到申请成功,如果没有提供就直接抛出异常bad_alloc。  operator new也是通过malloc来创建空间的。

    第二步当空间创建好之后就调用构造函数初始化对象

同样在销毁一个对象时也会经历两步:

    第一步执行delete Object 时会先调用析构函数对对象的资源进行清理。

    第二步调用operator delete来销毁对象,它实际是通过free来释放内存

三、一组对象的创建与销毁历程

    new object[N]

    创建一组对象时第一步先调用void* operator new[](count=sizeof(Object)*N+4),直接调用operator new(count)循环调用malloc来创建空间并且都判断申请是否成功以及失败时解决办法。在调用operator new[]中实际还是调用的operator new

    第二步先将前四个字节写上对象的个数,之后调用构造函数构造N个Object对象。

销毁一组对象时:delete[]  object

    第一步:先调用析构函数来释放N个对象的资源,清理对象的资源是倒着进行清理这是由于对象的生命周期不一样

    第二步:调用void operator delete[](void* ptr)实际也是调用void operator delete(void* ptr)来释放对象所在空间。最终是通过free(ptr)。

四、malloc/free与new/delete的区别:

     ①:malloc和free是函数,new和delete是操作符

     ②:malloc申请空间失败会返回NULL必须判空,二new不需要,但是需要捕捉异常

     ③:malloc不会对申请的空间进行初始化,而new会初始化

     ④:malloc需要明确知道申请空间的大小,而new后只跟上类型即可

     ⑤:malloc申请空间返回值必须进行强转,而new不用,因为它就跟着类型

     ⑥:申请自定义对象空间时,new和delete会分别调构造函数和析构函数。而malloc和free不会

造成这么多区别的原因就是malloc和free种种不太合适的问题,new和delete是在malloc和free上的一层封装。这和引用与指针的区别原因有很大的类似情况。

最后一点,动态申请空间不一定要释放空间,因为它不一定在堆上开辟空间也可能在栈上就比如:alloca函数下一篇将介绍此函数。

                                                                                                                                                珍&源码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值