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. 2238"回文字串"报告

    题目描述: 回文串,就是从前往后和从后往前看都是一样的字符串.那么现在给你一个字符串,请你找出该字符串中,长度最大的一个回文子串. 输入描述: 有且仅有一个仅包含小写字母的字符串,保证其长度不超过50 ...

  2. AJAX跨域的常见方法

    由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问.比如说你的网站域名是aaa.com,想要通过AJAX请求 ...

  3. 用js写一个回车键盘事件

    用js来监听键盘事件,代码如下: <script type="text/javascript" language=JavaScript charset="UTF-8 ...

  4. Odoo之Field

    字段描述符包含了字段的定义,下面是实例化一个字段时的属性: class Field(object): :param string: 字段标签(用户所见),如果不设置ORM将取用类的字段名(大写).:p ...

  5. 把int型非负数转换为英文

    数字转换为英文 输入为int型非负数,最大值为2^31 - 1 = 2 147 483 647 输出为String英文,最大输出为Two Billion One Hundred Forty Seven ...

  6. Spark SQL笔记——技术点汇总

    目录 概述 原理 组成 执行流程 性能 API 应用程序模板 通用读写方法 RDD转为DataFrame Parquet文件数据源 JSON文件数据源 Hive数据源 数据库JDBC数据源 DataF ...

  7. HDU6055 Regular polygon(计算几何)

    Description On a two-dimensional plane, give you n integer points. Your task is to figure out how ma ...

  8. POJ3614 Sunscreen 优先队列+贪心

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

  9. spring mvc4使用及json 日期转换解决方案

    spring mvc使用注解方式配制,以及对rest风格的支持,真是完美致极.下面将这两天研究到的问题做个总结,供参考.1.request对象的获取方式1:在controller方法上加入reques ...

  10. 使用jquery获取url及url参数的方法

    使用jquery获取url以及使用jquery获取url参数是我们经常要用到的操作 1.jquery获取url很简单,代码如下: window.location.href; 其实只是用到了javasc ...