valgrind 的 C++ 程序内存使用信息错误?

g0x*_*0x0 0 c++ memory valgrind

我正在使用 valgrind 使用此命令查找我的程序的内存使用情况

valgrind --tool=memcheck --leak-check=full -s --track-origins=yes ./memoryProblem
Run Code Online (Sandbox Code Playgroud)

它显示我的程序的总堆使用量为 72,704 字节

这是我的程序

#include <iostream>

int main(int argc, char const *argv[])
{
    int a[32768];
    std::cout << sizeof a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

int 是 4 个字节,32768*4 应该是 131,072 个字节,这也是程序的输出,但是为什么 valgrind 显示堆栈上数组的堆使用情况?

此外,我删除了 iostream 和 cout 并将数组大小减少到 10 个整数,这是输出:

==169343== Memcheck, a memory error detector
==169343== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==169343== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==169343== Command: ./memoryProblem
==169343== 
==169343== 
==169343== HEAP SUMMARY:
==169343==     in use at exit: 0 bytes in 0 blocks
==169343==   total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated
==169343== 
==169343== All heap blocks were freed -- no leaks are possible
==169343== 
==169343== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)

对于该程序:

int main(int argc, char const *argv[])
{
    int a[10];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么显示 72,704 字节?

我没有忘记编译我的程序

C++ 程序是否使用所有内存,我对它们如何工作感兴趣,或者 valgrind 是否使用该内存

我尝试将 valgrind 命令更改为

valgrind --tool=memcheck ./memoryProblem
Run Code Online (Sandbox Code Playgroud)

但结果相同

Kam*_*Cuk 5

为什么显示 72,704 字节?

你可以运行gdb并设置break malloc然后你会得到:

Breakpoint 1, 0x00007ffff7ae1320 in malloc () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff7ae1320 in malloc () from /usr/lib/libc.so.6
#1  0x00007ffff7e2326b in (anonymous namespace)::pool::pool (this=0x7ffff7f93240 <(anonymous namespace)::emergency_pool>)
    at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_alloc.cc:123
#2  __static_initialization_and_destruction_0 (__priority=65535, __initialize_p=1)
    at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_alloc.cc:262
#3  _GLOBAL__sub_I_eh_alloc.cc(void) () at /build/gcc/src/gcc/libstdc++-v3/libsupc++/eh_alloc.cc:338
#4  0x00007ffff7fdce2e in call_init () from /lib64/ld-linux-x86-64.so.2
#5  0x00007ffff7fdcf1c in _dl_init () from /lib64/ld-linux-x86-64.so.2
#6  0x00007ffff7fce0ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#7  0x0000000000000001 in ?? ()
#8  0x00007fffffffdf94 in ?? ()
#9  0x0000000000000000 in ?? ()
Run Code Online (Sandbox Code Playgroud)

现在我们可以从gcc/eh_alloc.c中读取:

Allocate exception objects.

...

pool::pool() {
     // Allocate the arena - we could add a GLIBCXX_EH_ARENA_SIZE environment
     // to make this tunable.
     arena_size = (EMERGENCY_OBJ_SIZE * EMERGENCY_OBJ_COUNT
          + EMERGENCY_OBJ_COUNT * sizeof (__cxa_dependent_exception));
     arena = (char *)malloc (arena_size);
Run Code Online (Sandbox Code Playgroud)

这是抛出异常时为构造对象保留的内存。另请参阅/sf/answers/3188696451/https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#cxx-intro

标准运行时初始化,例如为内存不足异常预先分配空间。

这很可能就是它的用途。