new/delete和malloc/free的异同

new/deletemalloc/free 的异同

在 C++ 中,new/deletemalloc/free 都可以用于动态内存分配,但它们有很多本质上的不同。主要区别包括:

  • 语法
  • 是否调用构造/析构函数
  • 返回类型
  • 是否需要手动指定内存大小
  • 异常处理
  • 可重载性

1. new/delete(C++)

newdelete 是 C++ 运算符,用于动态分配和释放对象,并且自动调用构造函数和析构函数

(1)基本语法

// 分配单个对象
ClassName* obj = new ClassName();  // 调用构造函数
delete obj;  // 调用析构函数
// 分配数组
ClassName* arr = new ClassName[5];  // 调用 5 次构造函数
delete[] arr;  // 调用 5 次析构函数

(2)特点

自动调用构造函数和析构函数
不需要指定内存大小new 通过 sizeof 自动计算)
支持重载(可以自定义 operator new
分配失败时抛出 std::bad_alloc 异常(可以用 nothrow 处理)


2. malloc/free(C 语言)

mallocfreeC 语言 的标准库函数,用于在 堆(heap)上分配和释放内存malloc 不会调用构造函数free 不会调用析构函数

(1)基本语法

// 分配单个对象
ClassName* obj = (ClassName*)malloc(sizeof(ClassName)); // 需要强制类型转换
free(obj);
// 分配数组
ClassName* arr = (ClassName*)malloc(5 * sizeof(ClassName));
free(arr);

(2)特点

不会调用构造函数和析构函数(必须手动 memset() 初始化)
必须手动指定大小malloc(sizeof(ClassName))
不会抛出异常(返回 NULL 表示分配失败)
不支持重载


3. new/delete vs malloc/free 对比

特性new/delete(C++)malloc/free(C)
调用构造/析构函数调用构造函数/析构函数不会调用,需手动初始化和清理
需要手动指定大小不需要new 自动计算)需要(必须使用 sizeof
返回类型返回正确的类型(无需强制转换)返回 void*,需要强制转换
失败处理抛出 std::bad_alloc 异常(可用 nothrow 处理)返回 NULL,需手动判断
适用语言C++C 语言(C++ 也能用,但不推荐)
性能更优化,底层可能会重载 operator new 进行优化较少优化,底层直接调用 malloc
数组分配new[]delete[] 需要成对使用❌ 直接 malloc/free,无数组管理

4. 什么时候用 new/delete,什么时候用 malloc/free

场景推荐方法说明
动态分配对象new/deleteC++ 代码中应优先使用 new,因为它会调用构造/析构函数
动态分配数组new[]/delete[]适用于 C++ 的数组对象,如 std::vector
分配 POD 类型数据(如 char*int*malloc/freemalloc 在 C 语言和某些性能敏感的场景下更合适
C 和 C++ 兼容代码malloc/freeC 语言项目中只能使用 malloc/free
异常安全性new/deletenew 遇到失败时抛出异常,而 malloc 返回 NULL

5. new 失败时的 nothrow 处理

默认情况下,如果 new 失败,会抛出 std::bad_alloc 异常:

try {
    int* p = new int[1000000000000];  // 可能失败
} catch (std::bad_alloc& e) {
    std::cout << "Allocation failed: " << e.what() << std::endl;
}

如果不希望抛异常,可以使用 nothrow

int* p = new(std::nothrow) int[1000000000000];
if (!p) {
    std::cout << "Memory allocation failed!" << std::endl;
}

malloc 直接返回 NULL,无需 try-catch


6. operator new/delete 的重载

C++ 允许重载 operator newoperator delete,用于自定义内存管理

#include <iostream>

class MyClass {
public:
    void* operator new(size_t size) {
        std::cout << "Custom new for size: " << size << std::endl;
        return malloc(size);  // 使用 malloc 分配内存
    }

    void operator delete(void* ptr) {
        std::cout << "Custom delete" << std::endl;
        free(ptr);  // 释放内存
    }
};

int main() {
    MyClass* obj = new MyClass();
    delete obj;
    return 0;
}

输出:

Custom new for size: 1
Custom delete

这种技术通常用于高性能系统,如游戏引擎或数据库,自定义内存池管理,提高分配效率。


7. 结论

new/delete 适用于 C++,尤其是对象管理

  • 调用构造函数和析构函数,适用于对象创建和销毁。
  • new 失败时抛出 std::bad_alloc 异常。
  • new[] 需要和 delete[] 搭配使用。

malloc/free 适用于 C 语言,或分配 POD 类型数据

  • 不会调用构造/析构函数,适合简单数据结构,如 char*int*
  • 返回 void*,需要手动转换类型
  • 返回 NULL 失败,不抛异常,适用于低级别 C 代码。

在 C++ 项目中,推荐尽量使用 new/delete,因为它们更安全、更可读、更符合 C++ 语法风格。而在 C 语言或对异常不敏感的系统代码中,可以使用 malloc/free


🔥 总结

特性new/delete(C++ 推荐)malloc/free(C 语言)
构造/析构✅ 自动调用❌ 需要手动初始化/释放
返回类型✅ 直接返回对象指针❌ 返回 void*,需强制转换
失败处理❌ 抛出异常 std::bad_alloc✅ 返回 NULL
适用场景✅ C++,对象管理✅ C 语言,POD 类型数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值