C++(22)—内存管理

文章目录

一、C语言动态内存管理回顾

1. malloc/calloc/realloc/free基本用法

C语言通过以下函数管理堆内存:

复制代码
malloc:分配指定字节数的未初始化内存

calloc:分配并清零内存(适合数组)

realloc:调整已分配内存的大小

free:释放内存

示例代码:

cpp 复制代码
void Test() {
    int* p1 = (int*)malloc(sizeof(int));  // 分配单个int空间
    int* p2 = (int*)calloc(4, sizeof(int));  // 分配4个int空间并清零
    int* p3 = (int*)realloc(p2, 10 * sizeof(int));  // 扩展为10个int空间
    
    free(p3);  // 只需释放realloc后的指针
    // free(p2);  // 错误!p2已被realloc释放
}

2. C语言内存管理的局限性

复制代码
不初始化对象:需手动初始化

类型不安全:返回void*需强制转换

无构造/析构:无法处理自定义类型的生命周期

二、C++内存管理方式:new与delete

1. new/delete操作内置类型

cpp 复制代码
void Test() {
    int* ptr1 = new int;          // 分配未初始化的int空间
    int* ptr2 = new int(10);      // 初始化为10
    int* ptr3 = new int[3];       // 分配3个int的数组

    delete ptr1;      // 释放单个元素
    delete ptr2;
    delete[] ptr3;    // 释放数组(必须用delete[])
}

2. new/delete操作自定义类型

**核心优势:**自动调用构造函数和析构函数

cpp 复制代码
class A {
public:
    A(int a = 0) : _a(a) { cout << "A()" << endl; }
    ~A() { cout << "~A()" << endl; }
private:
    int _a;
};

int main() {
    A* p1 = new A(1);       // 调用构造函数
    delete p1;              // 调用析构函数

    A* p2 = new A[3];       // 调用3次构造函数
    delete[] p2;            // 调用3次析构函数
    return 0;
}

三、new/delete的底层机制

1. operator new与operator delete

复制代码
operator new:全局函数,通过malloc申请空间,失败时抛出异常

operator delete:全局函数,通过free释放空间

伪代码解析:

cpp 复制代码
void* operator new(size_t size) {
    void* p = malloc(size);
    if (p == nullptr) throw bad_alloc();
    return p;
}

void operator delete(void* p) {
    free(p);
}

2. new/delete的实现原理

复制代码
new流程:

调用operator new分配内存

在分配的内存上调用构造函数

delete流程:

调用析构函数清理资源

调用operator delete释放内存

数组操作扩展:

new[]:调用operator new[],实际调用operator new分配连续空间

delete[]:调用每个元素的析构函数后释放内存

四、malloc/free与new/delete的对比

五、最佳实践与常见问题

1. 使用建议

复制代码
匹配使用:new与delete配对,new[]与delete[]配对

优先选择new/delete:尤其处理自定义类型时

异常安全:使用try-catch处理内存分配失败

2. 常见错误

复制代码
内存泄漏:未释放已分配内存

cpp
复制
int* p = new int;
// delete p;  // 忘记释放!
类型不匹配:混用delete和delete[]

cpp
复制
int* arr = new int[5];
delete arr;    // 错误!应用delete[]
悬垂指针:释放后继续访问指针

cpp
复制
int* p = new int(10);
delete p;
cout << *p;    // 危险!p指向已释放内存

六、总结

复制代码
C++内存管理优势:通过new/delete实现类型安全、自动构造/析构调用。

底层机制:依赖operator new/delete实现,本质仍基于malloc/free。

适用场景:优先使用new/delete,仅在需要与C代码交互时使用malloc/free。

掌握C++内存管理不仅能提升代码健壮性,还能有效避免内存泄漏等常见问题。理解其底层原理,将帮助开发者在复杂场景下做出更优设计决策。
相关推荐
??tobenewyorker15 分钟前
力扣打卡第二十一天 中后遍历+中前遍历 构造二叉树
数据结构·c++·算法·leetcode
蓝澈112123 分钟前
迪杰斯特拉算法之解决单源最短路径问题
java·数据结构
贾全36 分钟前
第十章:HIL-SERL 真实机器人训练实战
人工智能·深度学习·算法·机器学习·机器人
rzl0242 分钟前
java web5(黑马)
java·开发语言·前端
时序数据说1 小时前
为什么时序数据库IoTDB选择Java作为开发语言
java·大数据·开发语言·数据库·物联网·时序数据库·iotdb
GIS小天1 小时前
AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年7月4日第128弹
人工智能·算法·机器学习·彩票
jingling5551 小时前
面试版-前端开发核心知识
开发语言·前端·javascript·vue.js·面试·前端框架
oioihoii1 小时前
C++11 forward_list 从基础到精通:原理、实践与性能优化
c++·性能优化·list
满分观察网友z1 小时前
开发者的“右”眼:一个树问题如何拯救我的UI设计(199. 二叉树的右视图)
算法
m0_687399841 小时前
写一个Ununtu C++ 程序,调用ffmpeg API, 来判断一个数字电影的视频文件mxf 是不是Jpeg2000?
开发语言·c++·ffmpeg