C++内存管理:new/delete与内存泄漏实战
一、上期回顾掌握函数模板、类模板、泛型编程、模板特化理解了 STL 容器能适配任意类型的底层原因。今天攻坚C 内存管理搞定 new/delete、内存分区、野指针、内存泄漏四大核心痛点。二、C/C 程序内存五大分区程序运行时内存划分为 5 块面试必背栈区局部变量、函数形参、栈对象自动分配自动释放堆区new/malloc 开辟的空间手动申请手动释放全局 / 静态区全局变量、static 静态变量程序全程存在常量区字符串常量、const 全局常量只读不可修改代码区存放二进制程序指令只读三、malloc/free 与 new/delete 核心区别1. C 语言 malloc/free只分配原始内存不调用构造、析构函数需要强转类型、手动计算字节大小不会初始化内存int* p (int*)malloc(sizeof(int)); free(p);2. C new/delete分配内存 自动调用构造函数释放内存 自动调用析构函数无需计算大小、无需强转支持数组形式 new [] /delete []int* p new int; delete p; // 数组开辟 int* arr new int[5]; delete[] arr;核心区别总结new 自动调用构造malloc 只开空间new 无需强转、自动计算大小delete 自动调用析构free 直接回收内存数组必须配对new[]和delete[]四、new 的三种使用形式// 1. 普通开辟单个变量 int* p1 new int; // 2. 开辟并初始化 int* p2 new int(100); // 3. 开辟数组 int* p3 new int[5];五、内存泄漏成因与规避什么是内存泄漏堆空间用new申请后没有 delete 释放程序不退出内存一直占用。常见泄漏场景函数内 new没有返回也没有释放指针重新赋值旧地址丢失无法释放类中堆成员析构函数没写 delete避坑原则谁申请谁释放成对使用 new/delete六、野指针成因与危害野指针定义指向非法未知内存的指针没有有效指向。产生原因指针未初始化随机地址指针指向栈变量变量销毁后指针悬空内存释放后未把指针置空规避方法定义指针初始化为nullptr释放内存后立刻置空不访问悬空指针// 规范写法 int* p new int; delete p; p nullptr; // 置空避免野指针七、内存经典错误示范错误 1重复释放int* p new int; delete p; delete p; // 崩溃重复释放错误 2数组不匹配 delete []int* arr new int[5]; delete arr; // 错误必须 delete[]错误 3野指针访问int* p; *p 10; // 未初始化野指针崩溃八、构造析构与 new/delete 联动演示#include iostream using namespace std; class Test { public: Test(){cout 构造函数调用 endl;} ~Test(){cout 析构函数调用 endl;} }; int main() { // 栈对象自动构造、自动析构 Test t1; // 堆对象new触发构造delete触发析构 Test* t2 new Test; delete t2; return 0; }运行结果构造函数调用 构造函数调用 析构函数调用 析构函数调用九、今日核心总结内存五分区栈、堆、全局静态、常量、代码区new/delete 比 malloc/free 多了构造析构调用数组必须严格配对new[]和delete[]内存泄漏new 不 delete野指针未初始化 / 悬空指针开发规范指针初始化为空、释放后置空、成对申请释放十、课后练习用 new 开辟单个 int 并初始化delete 释放尝试不 delete 观察内存泄漏逻辑定义未初始化指针理解野指针危害