
目录1、C内存管理2、C内存管理方式3、operator new与operator delete函数4、new和delete的实现原理5、定位new表达式(placement-new)6、malloc/free和new/delete的区别一、C内存管理1、栈又叫堆栈–局部变量、函数参数、函数返回地址、临时变量栈是向下增长的。2. 堆用于程序运行时动态内存分配堆是可以上增长的。3. 数据段存储全局数据和静态数据。4. 代码段可执行的代码/只读常量。内核空间和内存映射段了解即可高地址 ┌─────────────────┐ │ 栈区 Stack │ ← 局部变量、函数参数、返回地址向下增长 ├─────────────────┤ │ 堆区 Heap │ ← malloc/new动态内存向上增长 ├─────────────────┤ │ 全局/静态区 Data │ ← 已初始化全局变量、static变量 │ BSS段 │ ← 未初始化全局变量默认0├─────────────────┤ │ 常量区 │ ← 字符串常量、const只读常量 ├─────────────────┤ │ 代码区 Text │ ← 函数指令、可执行代码 └─────────────────┘ 低地址二、C内存管理方式C语言内存管理方式在C中可以继续使用但有些地方就无能为力而且使用起来比较麻烦因此C又提出了自己的内存管理方式通过new和delete操作符进行动态内存管理。3.1 new/delete操作内置类型voidTest(){// 动态申请一个int类型的空间int*ptr4newint;// 动态申请一个int类型的空间并初始化为10int*ptr5newint(10);// 动态申请3个int类型的空间int*ptr6newint[3];deleteptr4;deleteptr5;delete[]ptr6;}注意申请和释放单个元素的空间使用new和delete操作符申请和释放连续的空间使用new[]和delete[]注意匹配起来使用。3.2 new和delete操作自定义类型#includeiostreamusingnamespacestd;// 自定义类classPerson{public:// 构造函数Person(){cout调用构造函数endl;}// 析构函数~Person(){cout调用析构函数endl;}};intmain(){// 1. new 单个自定义类型Person*pnewPerson;// 释放deletep;pnullptr;// 置空防止野指针cout---------endl;// 2. new 自定义类型数组Person*arrnewPerson[3];// 释放数组必须加 []delete[]arr;arrnullptr;return0;}注意在申请自定义类型的空间时new会调用构造函数delete会调用析构函数而malloc与free不会三、operator new与operator delete函数operator new / operator delete是全局库函数不是运算符重载new 关键字operator new调用构造函数delete 关键字 调用析构函数 operator delete(operator new内部调用malloc,operator delete内部调用freePerson*pnewPerson;// 等价两步// 1. void* raw operator new(sizeof(Person)); // 只开空间// 2. new (raw) Person; // 定位new调用构造operator new只分配堆内存不调用构造new 关键字分配内存 构造对象operator delete只释放内存不调用析构delete 关键字调用析构 释放内存全局默认函数原型// 分配内存void*operatornew(size_t size);// 释放内存voidoperatordelete(void*ptr);// 数组版本void*operatornew[](size_t size);voidoperatordelete[](void*ptr);四、new和delete的实现原理new类型 ↓1.申请堆内存(operatornew→ malloc)↓2.调用构造函数 ↓ 返回对象指针delete指针 ↓1.调用析构函数 ↓2.释放内存(operatordelete→ free)new 内存分配 (malloc) 构造函数delete 析构函数 内存释放 (free)new [] 分配内存 N 次构造delete [] N 次析构 释放内存malloc/free 不调用构造 / 析构 → 不能用来创建 C 对象new/delete 是 C 专为对象设计的五、定位new表达式(placement-new)不分配内存只在已有的内存上调用构造函数charbuf[100];Person*pnew(buf)Person;// 定位newp-~Person();// 手动析构operatordelete(p);六、malloc/free和new/delete的区别malloc/free和new/delete的共同点是都是从堆上申请空间并且需要用户手动释放。不同的地方是1.malloc和free是函数new和delete是操作符2.malloc申请的空间不会初始化new可以初始化3.malloc申请空间时需要手动计算空间大小并传递new只需在其后跟上空间的类型即可 如果是多个对象[]中指定对象个数即可4.malloc的返回值为void*, 在使用时必须强转new不需要因为new后跟的是空间的类型5.malloc申请空间失败时返回的是NULL因此使用时必须判空new不需要但是new需要捕获异常6. 申请自定义类型对象时malloc/free只会开辟空间不会调用构造函数与析构函数而new在申请空间后会调用构造函数完成对象的初始化delete在释放空间前会调用析构函数完成空间中资源的清理释放