0

I was using valgrind to find memory usage by my program using this command

valgrind --tool=memcheck --leak-check=full -s --track-origins=yes ./memoryProblem

it shows that the total heap usage by my program was 72,704 bytes

this is my program

#include <iostream>

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

an int is 4 bytes and 32768*4 should be 131,072 bytes which is also the output of the program but then why is valgrind showing heap usage for an array on stack?

Moreover, I removed iostream and cout and reduced size of array to 10 integers and this was the output:

==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)

for the program:

int main(int argc, char const *argv[])
{
    int a[10];
    return 0;
}

why is it showing 72,704 bytes?

and i did not forget to compile my program

Do C++ programs use all that memory, I'm interested in how they work or is it valgrind using that memory

i tried changing valgrind command to

valgrind --tool=memcheck ./memoryProblem

but same result

g0x0
  • 93
  • 7
  • ***and i did not forget to compile my program*** We trust you. It's damn hard to get anything out of valgrind without a compiled program – user4581301 Sep 04 '21 at 18:29
  • 4
    the 72,704 bytes is stuff in the [c++ runtime](https://stackoverflow.com/questions/3900549/what-is-runtime) that dynamically allocated storage for book-keeping or whatnot to allow your program to run. – user4581301 Sep 04 '21 at 18:31
  • 3
    `a` is not used and most compilers will optimise it out. It's stack memory and is not included in the heap report of valgrind anyway. – n. m. could be an AI Sep 04 '21 at 18:46
  • 2
    Compile your `g0.cc` C++ code with some recent [GCC](http://gcc.gnu.org/) -e.g. [GCC 10](https://gcc.gnu.org/gcc-10/) in 2021- invoked as `g++ -Wall -fverbose-asm -O -S g0.cc` then examine the generated `g0.s` assembler file. My guess is that `a` won't even be stack-allocated – Basile Starynkevitch Sep 04 '21 at 18:49
  • 1
    Don't forget that the initialization e.g. [crt0](https://en.wikipedia.org/wiki/Crt0) which calls `main` is doing many things. On a Linux system it is open source, and you are allowed to study (and improve) it. Details are a nightmare. – Basile Starynkevitch Sep 04 '21 at 18:53
  • @BasileStarynkevitch you were right there is no a there in the s file – g0x0 Sep 04 '21 at 19:15
  • @BasileStarynkevitch thank u for the interesting reply that helped alot also i have found that using cc and gcc as compiler does nothing on the stack valgrind is showing 0 bytes on heap but when i use g++ 72kb is used on the heap – g0x0 Sep 04 '21 at 19:16

1 Answers1

5

why is it showing 72,704 bytes?

You can run gdb and set break malloc and then you'll get:

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 ?? ()

So now we can read from 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);

This is the memory reserved for constructing objects when throwing an exception. Also see https://stackoverflow.com/a/45552806/9072753 also https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#cxx-intro:

Standard runtime initialization, e.g. pre-allocation of space for out-of-memory exceptions.

This is most probably what it's for.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111