new是C++语言级操作符,调用构造函数并管理对象生命周期;malloc是C库函数,仅分配原始内存且不涉及构造析构。二者不可混用,否则导致未定义行为。

new 和 malloc 的本质区别在哪
根本不在“谁更高级”,而在于 new 是 C++ 语言级操作符,会调用构造函数、支持类型安全;malloc 是 C 标准库函数,只做原始内存分配,不涉及对象生命周期管理。
常见错误是把 malloc 分配的内存直接 static_cast 成类指针然后调用成员函数——此时对象未构造,行为未定义。反过来,用 delete 释放 malloc 内存,或用 free 释放 new 内存,都是 UB(未定义行为)。
-
new底层通常调用operator new(可重载),再在返回地址上调用构造函数 -
malloc直接向堆管理器(如 ptmalloc、jemalloc)申请裸字节,不触发任何构造逻辑 -
new int[10]返回带类型信息的指针,malloc(10 * sizeof(int))返回void*,需显式转换
operator new 和 malloc 的底层调用链差异
两者最终都可能落到系统调用(如 mmap 或 sbrk),但中间封装层完全不同:
-
malloc属于 libc(如 glibc)的堆管理实现,维护空闲链表、chunk 元数据、合并/分割策略 -
operator new默认实现内部调用malloc(g++ 下),但它是个可替换的全局函数:你可以重载它,甚至让它返回 mmap 映射的匿名页 - 注意:
operator new抛出std::bad_alloc异常,而malloc失败返回nullptr,这是异常语义与错误码语义的根本分野
调试时可用 LD_PRELOAD 替换 malloc,但无法直接拦截 operator new——除非你重载它或 hook libc++ 的符号。
立即学习“C++免费学习笔记(深入)”;
为什么 delete[] 必须配 new[],free 却不区分数组
因为 new[] 在分配时可能额外写入数组长度(具体取决于编译器和标准库),供 delete[] 调用多次析构函数;malloc 完全不知道“数组”概念,它只管字节数。
- g++ 在 debug 模式下可能在
new[]前插入 4 字节记录元素个数;release 模式下不一定,但行为仍由标准保证 - 用
delete释放new[]分配的内存:只调用第一个对象的析构函数,其余未析构,且内存释放逻辑错位 -
free不关心你传的是不是数组指针,它只看 malloc 返回的 chunk header,所以free(p)对p = malloc(...)总是安全的
面试常被忽略的关键细节
真正拉开差距的不是背定义,而是知道哪些边界情况会崩:
-
new (std::nothrow) T返回nullptr而非抛异常,但依然会调用T的构造函数——如果构造函数自己抛异常,nothrow就失效了 -
operator new可以被声明为noexcept,但标准库默认版本不是;自定义版本若抛异常,会导致new行为异常 - placement new(如
new (buf) T)根本不分配内存,只调用构造函数;它对应的“销毁”必须手动调用t.~T(),不能delete
底层原理没那么神秘,但每层抽象(语言语义 → 运行时库 → 系统调用)都藏着容易误判的契约。别只记“new 调构造、malloc 不调”,得清楚谁在什么时候、依据什么规则做这件事。










