C++中程序存储空间除栈空间和静态区外,每个程序还拥有一个内存池,这部分内存被称为自由空间(free store)或堆(heap)。程序用堆来存储动态分配的对象,即,那些程序运行时分配的对象。动态对象的生存期由程序来控制 ,当动态对象不再使用时,程序必须显式的销毁它们。

new和delete的使用

C++中通过一对运算符new和delete来完成动态内存分配。new,在动态内存中为对象分配空间并返回一个指向该对象的指针,我们可以选择对对象初始化;delete接受一个动态对象的指针,销毁对象,并释放对应内存。使用示例如下:

 1 void Test()
2 {
3 int *pi1 = new int;
4 //pi1指向一个动态分配的4个字节(int型)、未初始化的无名对象;*pi1的值未定义
5 int *pi2 = new int(2);
6 //pi2指向的对象的值是2,动态分配4个字节( 1个 int) 的空间并初始化为2
7 int *pi3 = new int[3]; //动态分配12个字节( 3个 int) 的空间
8 int *pi4 = new int(); //值初始化为0;*pi4为0
9
10 delete pi1;
11 delete pi2;
12 delete [] pi3;
13 delete pi4;
14 }

自由空间分配的内存是无名的,new无法为其分配的对象命名,而是返回一个指向该对象的指针。默认情况下,动态分配的对象是默认初始化的,即内置类型或组合类型的对象的值是未定义的,类类型的对象将用默认构造函数进行初始化。
    new和delete、 new[] 和delete[] 一定匹配使用 , 一定匹配使用 , 一定匹配使用 ! ! ! 重要的事说三遍! 否则可能出现内存泄露甚至崩溃的问题。
深入探究new和delete、 new[] 和delete[]内部

通过下面这段代码我们来详细比较一下new和delete、 new[] 和delete[]内部实现

 1 class Array
2 {
3 public :
4 Array(size_t size = 10)//构造函数
5 : _size(size)
6 , _a(0)
7 {
8 cout << "Array(size_t size) " << endl;
9 if (_size > 0)
10 {
11 _a = new int[size];
12 }
13 }
14 ~Array() //析构函数
15 {
16 cout << "~Array() " << endl;
17 if (_a)
18 {
19 delete[] _a;
20 _a = 0;
21 _size = 0;
22 }
23 }
24 private:
25 int*_a;
26 size_t _size;
27 };
28 void Test()
29 {
30 Array* p1 = (Array*)malloc(sizeof(Array));
31 Array* p2 = new Array;
32 Array* p3 = new Array(20);
33 Array* p4 = new Array[10];
34 free(p1);
35 delete p2;
36 delete p3;
37 delete[] p4;
38 }
39 int main()
40 {
41 Test();
42 getchar();
43 return 0;
44 }

转到反汇编可以看到,在call指令处调用了operator new:

转到定义处可以看到operator new 的具体原型:

再按F10程序来到了析构函数

执行完之后,输出

此时new已经完成了申请空间的任务,然后调用构造函数创建对象。同样,detele的定义如下

delete先调用析构函数清除对象。然后调用operator detele释放空间。

Array* p4 = new Array[10];
delete[] p4;

执行这两条语句的时候实际上调用operator new[](10*sizeof(Array)+4)分配大小为10*sizeof(Array)+4空间,其中多的四个字节空间用于存放N(10)这个数字以便于delete中调用析构函数析构对象(调用析构函数的次数),空间申请好了之后调用构造函数创建对象。delete[] p4执行的时候首先取N(10)对象个数,然后调用析构函数析构对象,最后用operator delete[]函数释放空间。

总结:
1. operator new/operator delete operator new[] /operator delete[] 和 malloc/free用法一 样。
2. 他们只 负责分配空间/释放空间, 不会调用对象构造函数/析构函数来初始化/清理对象。
3. 实际operator new和operator delete只是malloc和free的一层封装。

【 new作用】 调用operator new分配空间。 调用构造函数初始化对象。

【 delete作用】 调用析构函数清理对象 调用operator delete释放空间

【 new[] 作用】 调用operator new分配空间。 调用N次构造函数分别初始化每个对象。

【 delete[] 作用】 调用N次析构函数清理对象。  调用operator delete释放空间。

C++动态内存管理之深入探究new和delete的更多相关文章

  1. C++—动态内存管理之深入探究new和delete

    C++中程序存储空间除栈空间和静态区外,每个程序还拥有一个内存池,这部分内存被称为自由空间(free store)或堆(heap).程序用堆来存储动态分配的对象,即,那些程序运行时分配的对象.动态对象 ...

  2. C++动态内存管理之shared_ptr、unique_ptr

    C++中的动态内存管理是通过new和delete两个操作符来完成的.new操作符,为对象分配内存并调用对象所属类的构造函数,返回一个指向该对象的指针.delete调用时,销毁对象,并释放对象所在的内存 ...

  3. uCGUI动态内存管理

    动态内存的堆区 /* 堆区共用体定义 */ typedef union { /* 可以以4字节来访问堆区,也可以以1个字节来访问 */ ]; /* required for proper aligne ...

  4. Keil C动态内存管理机制分析及改进(转)

    源:Keil C动态内存管理机制分析及改进 Keil C是常用的嵌入式系统编程工具,它通过init_mempool.mallloe.free等函数,提供了动态存储管理等功能.本文通过对init_mem ...

  5. (原创)动态内存管理练习 C++ std::vector<int> 模拟实现

    今天看了primer C++的 “动态内存管理类”章节,里面的例子是模拟实现std::vector<std::string>的功能. 照抄之后发现编译不通过,有个库函数调用错误,就参考着自 ...

  6. FreeRTOS 动态内存管理

    以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 动态内存管理,动态内存管理是 FreeRTOS 非常重要的一项功能,前面 ...

  7. C++程序设计入门 引用和动态内存管理学习

    引用: 引用就是另一个变量的别名,通过引用所做的读写操作实际上是作用于原变量上. 由于引用是绑定在一个对象上的,所以定义引用的时候必须初始化. 函数参数:引用传递 1.引用可做函数参数,但调用时只需 ...

  8. 动态内存管理详解:malloc/free/new/delete/brk/mmap

    c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, calloc/realloc 上述8个函数/操作符是c/c++语言里常用来做动 ...

  9. oracle结构-内存结构与动态内存管理

    内存结构与动态内存管理 内存是影响数据库性能的重要因素. oracle8i使用静态内存管理,即,SGA内是预先在参数中配置好的,数据库启动时就按这些配置来进行内在分配,oracle10g引入了动态内存 ...

随机推荐

  1. vijos1057题解

    题目: 永恒の灵魂最近得到了面积为n*m的一大块土地(高兴ING^_^),他想在这块土地上建造一所房子,这个房子必须是正方形的. 但是,这块土地并非十全十美,上面有很多不平坦的地方(也可以叫瑕疵).这 ...

  2. Threejs 开发3D地图实践总结

    前段时间连续上了一个月班,加班加点完成了一个3D攻坚项目.也算是由传统web转型到webgl图形学开发中,坑不少,做了一下总结分享. 1.法向量问题 法线是垂直于我们想要照亮的物体表面的向量.法线代表 ...

  3. js通过Date获取日期

    获取当前系统时间 var myDate = new Date();//获取系统当前时间 获取特定格式日期 myDate.getYear(); //获取当前年份(2位) myDate.getFullYe ...

  4. 英语曰曰曰No.523

    ---恢复内容开始--- [一句话新闻] The iPhone's 10th Anniversary:Can Apple Revive Its iPhone Sales ? 1.A look back ...

  5. Tomcat启动中的一些问题

    (a)在eclipse中启动tomcat,在控制台加载的配置却是其他项目的,有时候也不是自己工作空间里的? 出现的一个原因是:在我tomcat的webapp目录下,我放了一个其他项目的war包,在to ...

  6. select可选择、同时可自行输入

    HTML部分: <li class="bl-form-group"> <label>诊断医生</label> <div class=&qu ...

  7. POJ3614 Sunscreen 优先队列+贪心

    Description To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her ...

  8. 玛雅游戏[NOIP2011]

    题目描述 Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

  9. SSH项目过一段时间之后再访问会报一次Could not open Hibernate session for transaction 异常,Caused by: com.mysql.jdbc.CommunicationsException: Communications link failure due to underlyi,再重新方法即可访问成功(通常出现在过了一晚之后再去访问系统)

    前端时间到客户那去进行项目的上线测试,将项目部署好之后,运行都是正常的,可是每到了第二天早上访问的时候,就会报一个Could not open Hibernate session for transa ...

  10. 微信开发中遇到的问题,关于cdnmidimgurl 图片获取

    访问了微信服务器 返回的数据: [{MsgId=3349810483943419227, FromUserName=@@855c3ada0e9c387cfbcff93e9a1a639f024bcfd1 ...