2

At work I'm writing a rather complex piece of software in C, and I frequently test it using valgrind. The program so far works perfectly with no memory leaks or array-bounds violations, and in the valgrind report, the number of 'frees' matched the number of 'mallocs' - great. The thing that bugs me is that it reports thousands of frees and mallocs. And I know for a fact I'm not doing more than about 50-60. I do know that when my program calls 'fopen', that call is counted by valgrind toward the number of mallocs, and similarly 'fclose' is counted toward the number of 'frees'. But in my case, this still doesn't explain the numbers I'm seeing for how many times memory is being malloced and freed. I've scoured my code carefully looking for the culprit, but I got nothing. I can't post any code here for obvious reasons, but I just want to know, am I missing something? Are there other C operations that valgrind counts toward the number of mallocs and frees?

Here's my valgrind report. As you can see, everything looks good from this perspective.

Memcheck, a memory error detector
Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
Command: ./Codec
Parent PID: 3526

HEAP SUMMARY:
     in use at exit: 0 bytes in 0 blocks
   total heap usage: 2,407 allocs, 2,407 frees, 28,877,748 bytes allocated

 All heap blocks were freed -- no leaks are possible

 For counts of detected and suppressed errors, rerun with: -v
 ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
hauzer
  • 258
  • 3
  • 12
MoJoe
  • 31
  • 2
  • 3
    What about `for (int i = 0; i != 10000; ++i) { free(malloc(1)); }`? – Kerrek SB Oct 10 '13 at 20:08
  • 5
    If you are calling C library routines or are linking with any libraries and calling them, they can call malloc() and free(). – Charlie Burns Oct 10 '13 at 20:10
  • are you using any libraries? Often they will allocate and free memory behind the scenes – Pankrates Oct 10 '13 at 20:10
  • @KerrekSB: That's a nice hypothetical, but is the OP really doing that, especially if he says he is not? Is there information that Valgrind outputs that would shed some light on this? – Robert Harvey Oct 10 '13 at 20:10
  • 1
    Run the program under a debugger, and set a breakpoint on `malloc()`. Then do stack traces to see where it's being called from. – Barmar Oct 10 '13 at 20:11
  • 2
    "I can't post any code here for obvious reasons". Those reasons aren't that obvious, and reducing this to a well-documented [SSCCE](http://www.sscce.org) with specific numbers for your implementation would make your question considerably more robust, especially if said sample had a similar, yet minimized, workflow that your application does. As it stands now, the answer *is* obvious: If you're not calling those functions, then you're calling something that is. – WhozCraig Oct 10 '13 at 21:39
  • 1
    "Obvious reasons" refers to the fact that it's code I'm writing for work, not personal use. My work wouldn't like me giving out our code for all the web to have. Also, the answer is _not_ obvious. I'm perfectly aware that I'm calling _something_, probably indirectly through a C library like Charlie Burns and Pankrates suggested, that valgrind is interpreting as 'malloc' and 'free', but I can't tell what that something is. Therefore, I asked "Are there other C operations that valgrind counts toward the number of mallocs and frees?" My question did not require example code. – MoJoe Oct 10 '13 at 22:44

2 Answers2

0

Well, if you call library functions that perform the malloc and free calls you will be seeing lot many allocations and frees. some of the library functions, system calls that does allocations are strdup, pthread_create, timer_create, e.t.c

0

Remember that there's many function calls that could allocate memory, strdup, fopen, creating threads, loading shared objects, parsing timezone or locale information (as a time related function could require), 3.d party libraries could allocate memory in a number of ways, and so on.

But, run your program with the valgrind massif tool, http://valgrind.org/docs/manual/ms-manual.html (read those docs)

e.g.

 valgrind --depth=20  --tool=massif ./Calc

This produces a massif.out.XXX file which shows you various sources of allocations, and the snapshot of the heap, e.g. as an excerpt:

snapshot=9
#-----------
time=137984
mem_heap_B=640
mem_heap_extra_B=40
mem_stacks_B=0
heap_tree=peak
n2: 640 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
 n1: 352 0x4BFD095A: __fopen_internal (in /usr/lib/libc-2.17.so)
  n1: 352 0x4BFD0A39: fopen@@GLIBC_2.1 (in /usr/lib/libc-2.17.so)
   n0: 352 0x8048784: main (tailq_example.c:63)
 n5: 288 0x8048580: add_block (tailq_example.c:20)
  n0: 72 0x8048748: main (tailq_example.c:60)
  n0: 72 0x804875C: main (tailq_example.c:61)
  n0: 72 0x80487DC: main (tailq_example.c:72)
  n0: 72 0x80487F0: main (tailq_example.c:73)
  n0: 0 in 1 place, below massif's threshold (01.00%)
nos
  • 223,662
  • 58
  • 417
  • 506