9、C/C++ 内存管理详解:从基础到面试题
📘 C/C++ 内存管理详解:从基础到面试题
本文系统梳理了 C/C++ 中的内存分布、动态内存管理方式、new/delete 的底层原理,以及常见面试题,适合初学者和求职者参考。
🎯 本文目标
- 理解 C/C++ 程序的内存分布结构
- 掌握 C 语言中的动态内存管理函数:
malloc
/calloc
/realloc
/free
- 掌握 C++ 中的
new
/delete
操作符及其底层机制 - 理解定位 new 表达式(placement-new)
- 掌握常见面试题与内存泄漏检测方法
🧠 1. C/C++ 程序内存分布
C/C++ 程序运行时的内存通常分为以下几个区域:
区域 | 内容说明 |
---|---|
栈(Stack) | 局部变量、函数参数、返回地址等,向下增长 |
堆(Heap) | 动态分配的内存,向上增长 |
数据段 | 全局变量、静态变量 |
代码段 | 可执行代码和只读常量 |
内存映射段 | 文件映射、动态库、共享内存等 |
📌 示例变量归属
int globalvar = 1; // 数据段
static int staticGlobalvar = 1; // 数据段
void Test() {static int staticVar = 1; // 数据段int localvar = 1; // 栈int num1[10] = {1,2,3,4}; // 栈char char2[] = "abcd"; // 栈(字符数组)const char* pchar3 = "abcd";// 栈(指针)+ 代码段(字符串常量)int* ptr1 = (int*)malloc(4 * sizeof(int)); // 栈(指针)+ 堆(数据)
}
🧮 2. C语言动态内存管理函数
✅ 函数说明
函数 | 功能 |
---|---|
malloc | 分配指定大小的内存,内容未初始化 |
calloc | 分配并初始化为 0 |
realloc | 重新分配内存大小 |
free | 释放已分配的内存 |
📌 示例代码
int* p1 = (int*)malloc(sizeof(int));
free(p1);int* p2 = (int*)calloc(4, sizeof(int));
int* p3 = (int*)realloc(p2, sizeof(int) * 10);
free(p3); // 不需要再 free(p2)
🚀 3. C++ 的动态内存管理方式
C++ 提供了更高级的 new
/ delete
操作符,支持对象构造与析构。
✅ 基本用法
int* ptr1 = new int; // 分配一个 int
int* ptr2 = new int(10); // 分配并初始化
int* ptr3 = new int[3]; // 分配数组delete ptr1;
delete ptr2;
delete[] ptr3;
✅ 自定义类型支持构造/析构
class A {
public:A(int a = 0) : _a(a) { cout << "构造:" << this << endl; }~A() { cout << "析构:" << this << endl; }
private:int _a;
};A* p1 = new A(1);
delete p1;
🔍 4. operator new 与 operator delete 原理
✅ operator new
底层通过 malloc
分配空间,失败时尝试调用 _callnewh()
,最终可能抛出 bad_alloc
异常。
✅ operator delete
底层通过 free
释放空间,并进行内存块验证与线程锁保护。
⚙️ 5. new/delete 的实现原理
内置类型
new
与malloc
类似,但new
会抛异常,malloc
返回NULL
delete
与free
类似
自定义类型
new
:调用operator new
→ 构造函数delete
:析构函数 → 调用operator delete
new[]
/delete[]
:分别调用构造/析构函数 N 次
📦 6. 定位 new 表达式(placement-new)
用于在已分配的内存上构造对象,常用于内存池。
void* raw = malloc(sizeof(A));
A* obj = new(raw) A(10); // 构造对象
obj->~A(); // 手动析构
free(raw);
🎯 7. 常见面试题汇总
✅ malloc/free vs new/delete
对比项 | malloc/free | new/delete |
---|---|---|
类型 | 函数 | 操作符 |
初始化 | 不初始化 | 可初始化 |
类型安全 | 需强转 | 类型明确 |
错误处理 | 返回 NULL | 抛异常 |
构造/析构 | 不调用 | 自动调用 |
🧨 内存泄漏详解
什么是内存泄漏?
程序未释放已分配但不再使用的内存,导致资源浪费。
危害
- 程序响应变慢
- 系统资源耗尽
- 程序崩溃或卡死
示例
int* p = new int[10];
// 忘记 delete[] p; 就会造成泄漏
🛠️ 如何检测与避免内存泄漏
检测方法
- Windows:使用
_CrtDumpMemoryLeaks()
- Linux:使用 Valgrind 等工具
避免方法
- 良好编码规范
- 使用智能指针(RAII)
- 使用公司内部内存管理库
- 使用专业检测工具
✅ 总结
C/C++ 的内存管理是系统编程的核心技能,理解内存分布、掌握动态分配与释放机制、熟悉构造与析构行为,是写出高质量代码的基础。面试中常考这些知识点,建议配合代码练习与工具使用深入掌握。