嵌入式软件学习记录 - DAY3
malloc/free和new/delete在c和c++中的作用
·
一、基本作用
1. malloc/free(C 语言)
malloc:在堆上分配指定大小的内存块,返回void*指针(需手动转换类型)。free:释放malloc、calloc或realloc分配的内存块。
示例:
int* ptr = (int*)malloc(sizeof(int) * 10); // 分配 10 个 int 的内存
if (ptr == NULL) { /* 处理内存分配失败 */ }
free(ptr); // 释放内存
2. new/delete(C++)
new:动态分配内存,并自动调用对象的构造函数(初始化对象)。delete:调用对象的析构函数,并释放内存。
示例:
int* ptr = new int(10); // 分配并初始化为 10
delete ptr; // 释放内存
// 数组形式
int* arr = new int[5]; // 分配 5 个 int 的数组
delete[] arr; // 释放数组
二、核心区别
| 对比项 | malloc/free |
new/delete |
|---|---|---|
| 语言支持 | C 语言(C++ 兼容) | C++ 专用 |
| 内存分配方式 | 仅分配内存,不初始化对象 | 分配内存 + 调用构造函数(初始化对象) |
| 内存释放方式 | 仅释放内存,不调用析构函数 | 调用析构函数 + 释放内存 |
| 返回值类型 | void*(需手动转换为目标类型) |
直接返回目标类型的指针 |
| 错误处理 | 失败返回 NULL |
失败抛出 std::bad_alloc 异常 |
| 数组处理 | 使用 malloc(sizeof(T) * n) |
使用 new T[n] 和 delete[] |
| 自定义内存管理 | 可通过 malloc/free 实现自定义内存池 |
可重载 operator new/operator delete |
三、深入对比
1. 对象构造与析构
new/delete:- 自动调用构造函数和析构函数,适合管理 C++ 对象(如包含资源的类,如文件句柄、网络连接)。
class Resource { public: Resource() { /* 初始化资源 */ } ~Resource() { /* 释放资源 */ } }; Resource* r = new Resource(); // 构造函数被调用 delete r; // 析构函数被调用malloc/free:- 仅操作内存,不调用构造 / 析构函数,可能导致资源泄漏。
Resource* r = (Resource*)malloc(sizeof(Resource)); // 未初始化对象 free(r); // 未释放资源(析构函数未调用)
2. 类型安全性
new:自动推导类型,无需手动转换。int* p = new int; // 正确 // int* p = new char; // 编译错误:类型不匹配malloc:返回void*,需手动转换类型,可能引发错误。int* p = malloc(sizeof(int)); // C 语言允许隐式转换 int* p = (int*)malloc(sizeof(int)); // C++ 必须显式转换
3. 错误处理
new:默认在失败时抛出异常(如内存不足)。try { while (true) { char* p = new char[1000000]; // 最终会抛出 bad_alloc } } catch (const std::bad_alloc& e) { std::cerr << "Allocation failed: " << e.what() << std::endl; }malloc:失败返回NULL,需手动检查。void* p = malloc(1000000); if (p == NULL) { fprintf(stderr, "Allocation failed\n"); exit(1); }
4. 数组处理
new[]/delete[]:- 专门处理数组,记录数组大小并正确调用每个元素的析构函数。
std::string* arr = new std::string[3]; // 构造 3 个 string delete[] arr; // 析构 3 个 stringmalloc/free:- 需手动计算数组大小,且无法正确处理对象数组的析构。
std::string* arr = (std::string*)malloc(sizeof(std::string) * 3); free(arr); // 未调用析构函数,内存泄漏
四、使用场景
| 场景 | 推荐选择 | 原因 |
|---|---|---|
| C 语言编程 | malloc/free |
C 语言不支持 new/delete |
分配简单数据类型(如 int、char) |
malloc/free 或 new/delete |
均可,但 new/delete 更简洁且类型安全 |
| 分配 C++ 对象(含构造 / 析构函数) | new/delete |
必须使用 new/delete 确保对象正确初始化和资源释放 |
| 自定义内存管理(如内存池) | malloc/free |
可基于 malloc 实现底层内存分配,再封装为更高级的接口 |
| 与 C 库交互 | malloc/free |
保持内存分配 / 释放方式一致,避免混合使用导致的未定义行为 |
五、总结
- 优先使用
new/delete:在 C++ 中,处理对象时应优先选择new/delete,确保构造 / 析构函数被正确调用。 - 仅在必要时使用
malloc/free:与 C 代码兼容、实现底层内存管理或性能敏感场景(如频繁分配小对象)。 - 避免混合使用:
new必须与delete配对,malloc必须与free配对,否则会导致内存泄漏或未定义行为。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)