C++动态内存分配 new和malloc区别对比

new是C++运算符,自动调用构造函数并类型安全,malloc是C函数需手动计算内存且不调用构造函数,两者不可混用,推荐new与delete配对并优先使用智能指针。

在C++中,newmalloc 都可以用来动态分配内存,但它们在机制、使用方式和功能上存在本质区别。理解这些差异有助于写出更安全、高效的代码。

1. 所属语言与运行机制不同

new 是C++的运算符,属于C++语言的一部分,它在编译和运行时由编译器支持。调用 new 时,不仅分配内存,还会自动调用对象的构造函数。

malloc 是C语言中的库函数,定义在 (或C中的)中。它只负责分配原始内存块,不调用构造函数,也不了解C++对象模型。

2. 内存分配方式与类型安全

new 是类型安全的。使用时不需要手动计算字节数,编译器会根据对象类型自动确定所需内存大小。

例如:


MyClass* obj = new MyClass();
int* arr = new int[10];

malloc 需要手动指定字节数,且返回 void*,需要显式类型转换:


MyClass* obj = (MyClass*)malloc(sizeof(MyClass));
int* arr = (int*)malloc(10 * sizeof(int));

这种强制转换容易出错,且缺乏类型检查。

3. 构造函数与析构函数的调用

这是最关键的区别之一。

使用 new 创建对象时,会自动调用构造函数,确保对象被正确初始化。

使用 malloc 分配的内存是“未初始化”的,即使分配的是类对象,也不会调用构造函数。若要初始化,需手动调用构造函数(如 placement new),但不推荐普通使用。

同理,delete 会先调用析构函数再释放内存,而 free 只释放内存,不会调用析构函数。

4. 内存分配失败的处理方式

new 在内存不足时默认抛出 std::bad_alloc 异常,程序可捕获并处理。

如果使用 nothrow 版本(new(std::nothrow)),则返回空指针。

malloc 在失败时直接返回 nullptr,需要手动检查返回值。

5. 内存释放方式必须匹配

必须成对使用:

  • new → delete
  • new[] → delete[]
  • malloc → free

混用会导致未定义行为。例如用 free 释放 new 分配的内存,或用 delete 释放 malloc 的内存,可能造成资源泄漏或程序崩溃。

6. 重载与扩展性

newdelete 可以被重载,允许为特定类定制内存管理策略。

mallocfree 是标准C函数,无法重载。

基本上就这些。在C++中,推荐优先使用 newdelete(或更优的智能指针),避免混用 malloc/free。对于现代C++,建议进一步使用 std::unique_ptrstd::shared_ptr 等智能指针来自动管理内存,减少手动分配带来的风险。

以上就是C++动态内存分配 new和malloc区别对比的详细内容,更多请关注骃骐网【www.myinqi.com】。

相关推荐:

NumPy深拷贝浅拷贝区别_视图(View)与arr.copy()完全复制内存区分

view()不分配新内存而共享数据缓冲区,故修改视图即修改原数组;copy()分配新内存实现一层深拷贝,但object数组需deepcopy才彻底隔离。 为什么 arr.view() 修改原数组? 因为 view() 不分配新内存,只是换了个“眼镜”看同一块内存。它共享数据缓冲区(arr.data),改视图就等于改原数组。 常见错误现象:arr.view().fill(0) 后发现原 arr 全变...

为什么Python程序占用内存持续升高不释放_使用memory_profiler进行环境监控

memory_profiler仅统计每行新分配内存,不追踪对象生命周期或引用链,适合定位单次执行的内存尖峰,而非长周期泄漏;真正卡住内存的是强引用未释放,需用gc.get_referrers()或objgraph分析。 内存持续升高不释放,大概率不是“没回收”,而是对象还在被强引用着——memory_profiler能帮你看到哪行代码在吃内存,但不能告诉你谁在死死拽着它不放。 为什么memory_...

Python开发FastAPI怎么实现WebSocket在线人数统计_基于内存字典或Redis维护连接池

FastAPI中需用可哈希标识(如id(websocket)或user_id)增减在线人数,内存方案须加锁防竞态,多进程必须用Redis原子指令incr/decr维护共享计数,并配合心跳键实现高可用。 WebSocket连接建立时怎么安全地增减在线人数 FastAPI的WebSocket实例没有唯一ID,直接用websocket对象做字典键会报TypeError: unhashable type:...

Python怎么避免Flask应用遭遇内存溢出_控制大文件内存载入与及时显式del释放

应避免大文件读取时调用.read()等一次性加载方法,改用分块读取、流式处理、临时文件磁盘存储及作用域隔离,并通过MAX_CONTENT_LENGTH限制上传大小、禁用全局缓存、谨慎记录日志来防止内存溢出。 大文件读取时直接用 open().read() 会爆内存 Flask 默认没有请求体大小限制,用户上传一个 500MB 的文件,如果你写 request.files['file'].read(...

如何在Raspberry Pi上配置Python 3开发环境_优化内存占用与库安装

树莓派pip安装常卡在“Building wheel”阶段,因ARM架构编译资源有限、默认swap仅100MB,编译大库易OOM导致假死;需增大swap、换清华源(含apt主源、raspi.list和pip.conf)、优先用apt装预编译包(如sudo apt install python3-opencv),或强制二进制安装。 树莓派上直接用系统自带的 Python 3 就能跑基础脚本,但想稳定...

如何防止Python类实例动态添加新属性_通过__slots__优化内存与限制行为

用 slots 能有效禁止实例动态添加未声明的属性并降低内存占用,但需显式列出所有允许属性名,且禁用 __dict__;其原理是移除实例的属性字典而改用固定结构体存储。 直接说结论:用 __slots__ 能有效禁止实例动态添加未声明的属性,同时降低内存占用;但它不是“开关式”防护,一旦启用就必须显式列出所有允许的属性名,且会禁用 __dict__。 为什么 __slots__ 会阻止动态添加属性...

为什么Python中的sys.getsizeof结果不符合预期_理解Python对象的内存分配与容器机制

sys.getsizeof仅测量对象自身结构体大小,不包含其引用的子对象内存;真实总内存需用pympler.asizeof或tracemalloc分析。 sys.getsizeof 不是“对象总内存”的测量函数,它只返回对象头 + 直接持有的数据结构的字节大小,对容器类、自定义类、嵌套引用几乎全部失效。 sys.getsizeof 对列表/字典等容器只算“箱子本身”,不算“箱子里的东西” 列表在内...

如何在 PuLP 中限制每个任务仅由一名员工执行:引入二元分配变量与大M约束

本文详解如何使用 pulp 建模「每个任务最多分配给一名员工」的逻辑约束,通过分离二元分配变量(assign)与连续工作量变量(hours),结合大m法建立线性化关联,解决直接比较 lpvariable 与整数引发的 typeerror。 本文详解如何使用 pulp 建模「每个任务最多分配给一名员工」的逻辑约束,通过分离二元分配变量(assign)与连续工作量变量(hours),结合大m法建立线性...