目录
1. 内存分布
在C/C++程序中,内存主要分为以下几个区域:
- **栈(Stack)**:存储非静态局部变量、函数参数和返回值等,由编译器自动分配和释放,向下增长。
- **堆(Heap)**:用于程序运行时动态内存分配,由程序员手动管理(malloc/free, new/delete),向上增长。
- **数据段(静态区)**:存储全局变量和静态变量。
- **代码段(常量区)**:存储可执行代码和只读常量。
2. 动态内存管理
C语言方式:
- `malloc`:分配指定大小的内存,不初始化
- `calloc`:分配并清零内存
- `realloc`:调整已分配内存的大小
- `free`:释放内存
int* p1 = (int*)malloc(sizeof(int));
int* p2 = (int*)calloc(4, sizeof(int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
free(p3);
C++方式:
int* ptr4 = new int; // 分配一个int
int* ptr5 = new int(10); // 分配并初始化为10
int* ptr6 = new int[10]; // 分配10个int的数组
delete ptr4;
delete ptr5;
delete[] ptr6;
3. new/delete与malloc/free的区别
1. new/delete是操作符,malloc/free是函数
2. new会自动计算大小,malloc需要手动计算
3. new会调用构造函数,delete会调用析构函数
4. new失败时抛出异常,malloc返回NULL
5. new返回类型指针,malloc返回void*需要强制转换
4. operator new与operator delete
这两个是全局函数,new底层调用operator new,delete底层调用operator delete。operator new实际通过malloc实现,operator delete实际通过free实现。
5. 定位new表达式
在已分配的内存上构造对象:
A* p1 = (A*)malloc(sizeof(A));
new(p1)A; // 调用构造函数
p1->~A(); // 显式调用析构函数
free(p1);
6. 内存泄漏
内存泄漏是指程序未能释放不再使用的内存。危害包括程序性能下降直至崩溃。
避免内存泄漏的方法:
1. 良好的编码规范,确保分配与释放配对
2. 使用RAII或智能指针管理资源
3. 使用内存检测工具(如_CrtDumpMemoryLeaks)
总结
C++内存管理比C更安全方便,特别是对于自定义类型。理解内存分布和管理方式对于写出高效、安全的代码至关重要。智能指针(如unique_ptr, shared_ptr)是现代C++中更推荐的内存管理方式,可以自动管理生命周期,减少内存泄漏风险。