2025-08-27 ·
日常编程 ·
207898
new是C++运算符,自动调用构造函数并类型安全,malloc是C函数需手动计算内存且不调用构造函数,两者不可混用,推荐new与delete配对并优先使用智能指针。
在C++中,new 和 malloc 都可以用来动态分配内存,但它们在机制、使用方式和功能上存在本质区别。理解这些差异有助于写出更安全、高效的代码。
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. 重载与扩展性
new 和 delete 可以被重载,允许为特定类定制内存管理策略。
malloc 和 free 是标准C函数,无法重载。
基本上就这些。在C++中,推荐优先使用 new 和 delete (或更优的智能指针),避免混用 malloc/free。对于现代C++,建议进一步使用 std::unique_ptr 、std::shared_ptr 等智能指针来自动管理内存,减少手动分配带来的风险。
以上就是C++动态内存分配 new和malloc区别对比的详细内容,更多请关注骃骐网【www.myinqi.com】。
view()不分配新内存而共享数据缓冲区,故修改视图即修改原数组;copy()分配新内存实现一层深拷贝,但object数组需deepcopy才彻底隔离。 为什么 arr.view() 修改原数组? 因为 view() 不分配新内存,只是换了个“眼镜”看同一块内存。它共享数据缓冲区(arr.data),改视图就等于改原数组。 常见错误现象:arr.view().fill(0) 后发现原 arr 全变...
2026-05-29 · 日常编程 · 294186
memory_profiler仅统计每行新分配内存,不追踪对象生命周期或引用链,适合定位单次执行的内存尖峰,而非长周期泄漏;真正卡住内存的是强引用未释放,需用gc.get_referrers()或objgraph分析。 内存持续升高不释放,大概率不是“没回收”,而是对象还在被强引用着——memory_profiler能帮你看到哪行代码在吃内存,但不能告诉你谁在死死拽着它不放。 为什么memory_...
2026-05-29 · 日常编程 · 291699
FastAPI中需用可哈希标识(如id(websocket)或user_id)增减在线人数,内存方案须加锁防竞态,多进程必须用Redis原子指令incr/decr维护共享计数,并配合心跳键实现高可用。 WebSocket连接建立时怎么安全地增减在线人数 FastAPI的WebSocket实例没有唯一ID,直接用websocket对象做字典键会报TypeError: unhashable type:...
2026-05-28 · 日常编程 · 139321
应避免大文件读取时调用.read()等一次性加载方法,改用分块读取、流式处理、临时文件磁盘存储及作用域隔离,并通过MAX_CONTENT_LENGTH限制上传大小、禁用全局缓存、谨慎记录日志来防止内存溢出。 大文件读取时直接用 open().read() 会爆内存 Flask 默认没有请求体大小限制,用户上传一个 500MB 的文件,如果你写 request.files['file'].read(...
2026-05-28 · 日常编程 · 35047
树莓派pip安装常卡在“Building wheel”阶段,因ARM架构编译资源有限、默认swap仅100MB,编译大库易OOM导致假死;需增大swap、换清华源(含apt主源、raspi.list和pip.conf)、优先用apt装预编译包(如sudo apt install python3-opencv),或强制二进制安装。 树莓派上直接用系统自带的 Python 3 就能跑基础脚本,但想稳定...
2026-05-28 · 日常编程 · 226430
用 slots 能有效禁止实例动态添加未声明的属性并降低内存占用,但需显式列出所有允许属性名,且禁用 __dict__;其原理是移除实例的属性字典而改用固定结构体存储。 直接说结论:用 __slots__ 能有效禁止实例动态添加未声明的属性,同时降低内存占用;但它不是“开关式”防护,一旦启用就必须显式列出所有允许的属性名,且会禁用 __dict__。 为什么 __slots__ 会阻止动态添加属性...
2026-05-25 · 日常编程 · 20206
sys.getsizeof仅测量对象自身结构体大小,不包含其引用的子对象内存;真实总内存需用pympler.asizeof或tracemalloc分析。 sys.getsizeof 不是“对象总内存”的测量函数,它只返回对象头 + 直接持有的数据结构的字节大小,对容器类、自定义类、嵌套引用几乎全部失效。 sys.getsizeof 对列表/字典等容器只算“箱子本身”,不算“箱子里的东西” 列表在内...
2026-05-25 · 日常编程 · 105632
本文详解如何使用 pulp 建模「每个任务最多分配给一名员工」的逻辑约束,通过分离二元分配变量(assign)与连续工作量变量(hours),结合大m法建立线性化关联,解决直接比较 lpvariable 与整数引发的 typeerror。 本文详解如何使用 pulp 建模「每个任务最多分配给一名员工」的逻辑约束,通过分离二元分配变量(assign)与连续工作量变量(hours),结合大m法建立线性...
2026-05-24 · 日常编程 · 277639
os.cpu_count() 返回 None 时应改用 os.sched_getaffinity(0)(Linux/macOS)或 psutil.cpu_count(),后者可区分逻辑核与物理核;内存需用 psutil.virtual_memory().total 获取;容器中须读取 cgroups 接口而非依赖 os.cpu_count()。 os.cpu_count() 返回 None 怎么办...
2026-05-24 · 日常编程 · 136853
view报错“Tensor is not contiguous”是因为其要求输入张量内存连续,而transpose等操作仅修改stride不复制数据,导致is_contiguous()为False;需显式调用contiguous()或改用reshape/flatten等替代方案。 为什么 view 会报错 “Tensor is not contiguous” 当你对一个张量调用 view、resh...
2026-05-24 · 日常编程 · 213845