浅谈c++ new、delete与malloc和free

  malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete。

malloc与new:

  malloc是c语言的库函数,其作用是在内存中开辟一块连续的指定大小的内存空间(注意:调用malloc必须要指定开辟的空间大小),返回指向该被分配内存的指针(该指针为void * ,需要通过强制类型转换将void*指针转换成我们需要的类型)。

//用例
int* ptr = (int*) malloc (sizeof(int)) //分配一个int类型大小的空间
float* ptr2 = (float*) malloc (sizeof(int)) //分配float类型大小空间

一般情况下 malloc总是能成功分配一块连续的内存空间,但当内存耗尽或者内存过于碎片化而不足以开辟固定大小的连续空间的时候,malloc则调用失败,这时候malloc会返回一个空指针NULL,所以每次使用malloc时以防万一都应该先判断其返回指针是否为空防止。

  new是c++提供的一个操纵符(或者说关键字)。其也是用于分配内存的。其调用过程可以分解为三个步骤:

    1、调用operator new(可重载函数)分配内存

    2、在所分配的内存中调用对象的构造函数,构造对象

    3、返回指向该内存空间的指针

  值得一提的是,new内部开辟内存空间的原理也是调用malloc函数,其调用过程被封装在operator new内部,可以说new是在malloc的基础上再封装了一系列功能。与malloc有所区别的是,new在operator new开辟出空间后,会调用对象的构造函数在该空间中构造对象最后返回对象,而malloc只负责开辟空间,并不负责构造对象;并且new 在分配空间失败后并不是返回空指针而是抛出一个 std::bad_alloc 异常。

 

delete与free:

  free与delete的作用与上面提到的new和delete相反。free函数只需传入指向某一块已分配内存的指针,便能自动释放掉这些内存。而为何调用malloc需要传入开辟空间大小而free不用传入需要释放的空间大小呢?其实原因在于malloc分配空间的时候,不仅会按照传入参数大小分配空间大小,还会在该段内存头部和尾部插入一些额外的信息(俗称cookie),其中包含了内存大小的信息。这样free函数只需要读取该信息,便可以知道要释放的内存大小、范围等。

  而delete调用过程则与new相反,其调用过程也同样可以分解:

    1、调用对象的析构函数

    2、调用operator delete

  delete与new 相对应,其释放内存空间的原理也是调用free函数,其调用过程被封装在operator delete内部,即delete是在free的基础上封装了一系列功能。delete首先调用对象的析构函数,然后底层调用free释放该区域内存。

关于c++内存管理的知识可以阅读候捷老师的一系列书籍以及视频,其中对c++内部原理的解析十分透彻,每一次读都可以读到新的感悟。

猜你喜欢

转载自www.cnblogs.com/LEEYATWAH/p/11577587.html