一、基本作用

1. malloc/free(C 语言)
  • malloc:在堆上分配指定大小的内存块,返回 void* 指针(需手动转换类型)。
  • free:释放 malloccalloc 或 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 个 string
    
  • malloc/free
    • 需手动计算数组大小,且无法正确处理对象数组的析构。
    std::string* arr = (std::string*)malloc(sizeof(std::string) * 3);
    free(arr);  // 未调用析构函数,内存泄漏
    

四、使用场景

场景 推荐选择 原因
C 语言编程 malloc/free C 语言不支持 new/delete
分配简单数据类型(如 intchar 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 配对,否则会导致内存泄漏或未定义行为。
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐