news 2026/5/10 11:06:02

C++内存管理:new/delete与内存泄漏实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++内存管理:new/delete与内存泄漏实战

一、上期回顾

掌握函数模板、类模板、泛型编程、模板特化,理解了 STL 容器能适配任意类型的底层原因。今天攻坚C++ 内存管理,搞定 new/delete、内存分区、野指针、内存泄漏四大核心痛点。

二、C/C++ 程序内存五大分区

程序运行时内存划分为 5 块,面试必背:

  1. 栈区:局部变量、函数形参、栈对象;自动分配自动释放
  2. 堆区:new/malloc 开辟的空间;手动申请手动释放
  3. 全局 / 静态区:全局变量、static 静态变量;程序全程存在
  4. 常量区:字符串常量、const 全局常量;只读不可修改
  5. 代码区:存放二进制程序指令,只读

三、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;

核心区别总结

  1. new 自动调用构造,malloc 只开空间
  2. new 无需强转、自动计算大小
  3. delete 自动调用析构,free 直接回收内存
  4. 数组必须配对new[]delete[]

四、new 的三种使用形式

// 1. 普通开辟单个变量 int* p1 = new int; // 2. 开辟并初始化 int* p2 = new int(100); // 3. 开辟数组 int* p3 = new int[5];

五、内存泄漏成因与规避

什么是内存泄漏

堆空间用new申请后,没有 delete 释放,程序不退出内存一直占用。

常见泄漏场景

  1. 函数内 new,没有返回也没有释放
  2. 指针重新赋值,旧地址丢失无法释放
  3. 类中堆成员,析构函数没写 delete

避坑原则

谁申请,谁释放;成对使用 new/delete


六、野指针成因与危害

野指针定义

指向非法未知内存的指针,没有有效指向。

产生原因

  1. 指针未初始化,随机地址
  2. 指针指向栈变量,变量销毁后指针悬空
  3. 内存释放后,未把指针置空

规避方法

  1. 定义指针初始化为nullptr
  2. 释放内存后立刻置空
  3. 不访问悬空指针
// 规范写法 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; }

运行结果:

构造函数调用 构造函数调用 析构函数调用 析构函数调用

九、今日核心总结

  1. 内存五分区:栈、堆、全局静态、常量、代码区
  2. new/delete 比 malloc/free 多了构造析构调用
  3. 数组必须严格配对new[]delete[]
  4. 内存泄漏:new 不 delete;野指针:未初始化 / 悬空指针
  5. 开发规范:指针初始化为空、释放后置空、成对申请释放

十、课后练习

  1. 用 new 开辟单个 int 并初始化,delete 释放
  2. 尝试不 delete 观察内存泄漏逻辑
  3. 定义未初始化指针,理解野指针危害
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 11:02:06

对比直接使用官方sdk体验taotoken聚合调用的便捷之处

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 对比直接使用官方 SDK 体验 Taotoken 聚合调用的便捷之处 在开发实践中&#xff0c;当项目需要接入多个不同厂商的大模型能力时&am…

作者头像 李华
网站建设 2026/5/10 10:59:31

深度解析SMUDebugTool:AMD Ryzen处理器底层硬件调试架构剖析

深度解析SMUDebugTool&#xff1a;AMD Ryzen处理器底层硬件调试架构剖析 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: http…

作者头像 李华
网站建设 2026/5/10 10:57:39

浏览器中零配置查看SQLite数据库:你的数据探索新利器

浏览器中零配置查看SQLite数据库&#xff1a;你的数据探索新利器 【免费下载链接】sqlite-viewer View SQLite file online 项目地址: https://gitcode.com/gh_mirrors/sq/sqlite-viewer 你是否曾因一个简单的SQLite文件而被迫安装臃肿的数据库管理软件&#xff1f;或者…

作者头像 李华
网站建设 2026/5/10 10:56:46

Sloppy开发哲学:在可控范围内拥抱不完美,加速软件交付

1. 项目概述&#xff1a;一个“不完美”但高效的开发哲学在软件开发的日常里&#xff0c;我们常常被“完美主义”所困。每一次代码提交都力求优雅&#xff0c;每一个功能设计都追求极致&#xff0c;每一次重构都希望一劳永逸。但现实往往是&#xff0c;在快速迭代的业务需求面前…

作者头像 李华
网站建设 2026/5/10 10:55:32

飞行器姿态解算——欧拉角法:从二维旋转到三维姿态的数学桥梁

1. 从二维旋转开始理解坐标系变换 第一次接触飞行器姿态解算时&#xff0c;看到那些复杂的坐标系变换公式&#xff0c;相信很多人和我一样感到头疼。但别担心&#xff0c;我们可以从最基础的二维旋转开始&#xff0c;循序渐进地理解这个看似复杂的问题。 想象一下你在纸上画了一…

作者头像 李华