You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中malloc与new的内存占用差异及内存管理疑问

malloc与new的内存分配量差异问题

通过Valgrind检测发现,简单C++程序中使用malloc和new时,总内存分配量存在显著差异,以下是测试代码及对应Valgrind输出:

使用malloc的版本

#include <cstdlib>
int main() {
    int* a = (int *)malloc(4);
    return 0;
}

对应的Valgrind输出:

==34673== HEAP SUMMARY:
==34673==     in use at exit: 4 bytes in 1 blocks
==34673==   total heap usage: 1 allocs, 0 frees, 4 bytes allocated

使用new的版本

int main() {
    int* a = new int;
    return 0;
}

对应的Valgrind输出:

==35295== HEAP SUMMARY:
==35295==     in use at exit: 4 bytes in 1 blocks
==35295==   total heap usage: 2 allocs, 1 frees, 72,708 bytes allocated

疑问

  • 为何两者的总堆内存使用量差异如此巨大?new版本的分配字节数远多于malloc版本,这是否和C++ new的内部内存管理机制有关?
  • 另外,仅包含<iostream>的空程序:
#include <iostream>
int main() {
    return 0;
}

也存在72704B的内存开销,这部分开销似乎和动态内存管理相关,但不清楚为何数值这么大。

使用的工具版本

g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
valgrind-3.18.1

编译及检测命令:g++ program_name.cpp,随后执行valgrind ./a.out


原因解析

  1. new与malloc的差异根源
    你看到的额外内存分配,并非new int本身导致,而是C标准库的全局内存分配器初始化造成的。当程序中首次调用new时,C运行时会初始化其内置的内存分配器(比如GCC的libstdc++使用的ptmalloc2变种),这个初始化过程会预先分配一块内存池用于后续小内存分配的优化,这就是Valgrind统计到的额外72KB左右的内存。而malloc属于C标准库的分配函数,它的初始化逻辑和C++的内存分配器是分开的,在这个简单程序里没有触发额外的池化内存分配。

  2. iostream带来的内存开销
    当你包含<iostream>头文件时,程序启动阶段会初始化标准输入输出流对象(比如std::cin、std::cout),这些对象的构造过程会间接触发C内存分配器的初始化,同样会分配那块72KB左右的内存池。这也是为什么空的iostream程序也会有这个开销——和new的情况本质一样,都是触发了C标准库内存分配器的预初始化。

  3. 关于Valgrind的统计逻辑
    Valgrind会统计所有堆上的分配操作,包括标准库内部的隐式分配。虽然这些内存最后会被标准库在程序退出前释放(所以in use at exit里没有统计到),但total heap usage会把所有曾经分配过的内存都算进去,这就是为什么new版本和iostream程序的总分配量远大于实际业务代码的分配量。


内容的提问来源于stack exchange,提问作者sajad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:43:15