Memory leak in libmagic? - c

Trynig some test code for libmagic:
#include <magic.h>
#include <stdio.h>
int main(int argc, char **argv) {
magic_t cookie;
cookie = magic_open(MAGIC_MIME_TYPE);
if (cookie == NULL) {
perror(magic_error(cookie));
return 1;
}
if (magic_load(cookie, NULL) == -1) {
perror(magic_error(cookie));
return 1;
}
const char *string = magic_file(cookie, *(argv+1));
if (string == NULL) {
perror(magic_error(cookie));
return 1;
}
printf("%s\n", string);
magic_close(cookie);
return 0;
}
The code is pretty much ripped from here:
http://vivithemage.co.uk/blog/?p=105
The code runs ok, but using valgrind --leak-check=full ./libmagic /path/to/some/image/file a memleak from the library is reported:
==6153== HEAP SUMMARY:
==6153== in use at exit: 48 bytes in 3 blocks
==6153== total heap usage: 36 allocs, 33 frees, 990,559 bytes allocated
==6153==
==6153== 48 bytes in 1 blocks are definitely lost in loss record 2 of 2
==6153== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6153== by 0x4E43D3D: ??? (in /usr/lib/x86_64-linux-gnu/libmagic.so.1.0.0)
==6153== by 0x4E447ED: ??? (in /usr/lib/x86_64-linux-gnu/libmagic.so.1.0.0)
==6153== by 0x4008A8: main (libmagic.c:15)
==6153==
==6153== LEAK SUMMARY:
==6153== definitely lost: 48 bytes in 1 blocks
==6153== indirectly lost: 0 bytes in 2 blocks
==6153== possibly lost: 0 bytes in 0 blocks
==6153== still reachable: 0 bytes in 0 blocks
==6153== suppressed: 0 bytes in 0 blocks
Do I need something else than magic_close() to wrap up, or is there some weakness in the library?
magic.h says MAGIC_VERSION 524, I'm using gcc 5.4.0

I just came across the same issue today, it seems there was an defect reported about it:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=840754
According to the discussion there it should be fixed in the latest version.

Related

Fork after malloc causing memory leak

I'm working on a system programming project that requires forking N process. The issue is I'm keeping the PID's in a dynamicly allocated array and valgrind with "--leak-check=full --show-leak-kinds=all" flags shows this PID array pointer as possible leak.
pid_t *pid;
//...globals & prototypes
int main(int argc, char *argv[])
{
//... Input parsing
// Create actor process=========================================
pid = malloc((_N + _V + _C + 1) * sizeof(pid_t *)); // LINE VALGRIND IS POINTING STILL REACHABLE
for (int i = 0; i < _N + _V + _C + 1; i++)
{
pid[i] = fork();
if (pid[i] == 0)
break;
}
// ======================================== Create actor process
// Parent process ====================================================
if (parent_pid == getpid())
{
// Wait for all the childeren=====================================
for (int i = 0; i < _N + _V + _C + 1 || exit_requested != 0; i++)
{
int status;
if (waitpid(pid[i], &status, 0) == -1)
{
errExit("waitpid");
}
}
// =====================================Wait for all the childeren
// Free resources
free(pid);
//.. destroy semaphores
shm_unlink(SHARED_LINK);
}
// Child processes ===================================================
else
{
for (int i = 0; i < _N + _V + _C + 1; i++)
{
if (i >= 0 && i < _N && pid[i] == 0)
{
producer(_I, shared_data, i);
}
else if (i >= _N && i < _N + _V && pid[i] == 0)
{
mid_consumer(shared_data, i - _N);
}
else if (i >= _N + _V && i < _N + _V + _C && pid[i] == 0)
{
end_consumer(shared_data, i - _N - _V);
}
}
}
// ===================================================================
return 0;
}
Here is the valgrind output
==8056== Memcheck, a memory error detector
==8056== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8056== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8056== Command: ./program -n 2 -v 2 -c 4 -b 81 -t 2 -i cold_storage.txt
==8056== Parent PID: 8055
==8056==
==8061==
==8061== HEAP SUMMARY:
==8061== in use at exit: 72 bytes in 1 blocks
==8061== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8061==
==8061== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8061== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8061== by 0x10925D: main (main.c:169)
==8061==
==8061== LEAK SUMMARY:
==8061== definitely lost: 0 bytes in 0 blocks
==8061== indirectly lost: 0 bytes in 0 blocks
==8061== possibly lost: 0 bytes in 0 blocks
==8061== still reachable: 72 bytes in 1 blocks
==8061== suppressed: 0 bytes in 0 blocks
==8061==
==8061== For counts of detected and suppressed errors, rerun with: -v
==8061== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8059==
==8059== HEAP SUMMARY:
==8059== in use at exit: 72 bytes in 1 blocks
==8059== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8059==
==8057==
==8062==
==8057== HEAP SUMMARY:
==8057== in use at exit: 72 bytes in 1 blocks
==8057== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8057==
==8062== HEAP SUMMARY:
==8062== in use at exit: 72 bytes in 1 blocks
==8062== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8062==
==8059== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8059== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8059== by 0x10925D: main (main.c:169)
==8059==
==8059== LEAK SUMMARY:
==8059== definitely lost: 0 bytes in 0 blocks
==8059== indirectly lost: 0 bytes in 0 blocks
==8059== possibly lost: 0 bytes in 0 blocks
==8059== still reachable: 72 bytes in 1 blocks
==8059== suppressed: 0 bytes in 0 blocks
==8059==
==8059== For counts of detected and suppressed errors, rerun with: -v
==8059== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8062== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8057== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8062== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8057== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8062== by 0x10925D: main (main.c:169)
==8062==
==8057== by 0x10925D: main (main.c:169)
==8062== LEAK SUMMARY:
==8057==
==8062== definitely lost: 0 bytes in 0 blocks
==8057== LEAK SUMMARY:
==8062== indirectly lost: 0 bytes in 0 blocks
==8057== definitely lost: 0 bytes in 0 blocks
==8062== possibly lost: 0 bytes in 0 blocks
==8057== indirectly lost: 0 bytes in 0 blocks
==8062== still reachable: 72 bytes in 1 blocks
==8057== possibly lost: 0 bytes in 0 blocks
==8062== suppressed: 0 bytes in 0 blocks
==8057== still reachable: 72 bytes in 1 blocks
==8062==
==8057== suppressed: 0 bytes in 0 blocks
==8062== For counts of detected and suppressed errors, rerun with: -v
==8057==
==8062== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8057== For counts of detected and suppressed errors, rerun with: -v
==8057== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8063==
==8063== HEAP SUMMARY:
==8063== in use at exit: 72 bytes in 1 blocks
==8063== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8063==
==8063== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8063== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8063== by 0x10925D: main (main.c:169)
==8063==
==8063== LEAK SUMMARY:
==8063== definitely lost: 0 bytes in 0 blocks
==8063== indirectly lost: 0 bytes in 0 blocks
==8063== possibly lost: 0 bytes in 0 blocks
==8063== still reachable: 72 bytes in 1 blocks
==8063== suppressed: 0 bytes in 0 blocks
==8063==
==8063== For counts of detected and suppressed errors, rerun with: -v
==8063== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8058==
==8058== HEAP SUMMARY:
==8058== in use at exit: 72 bytes in 1 blocks
==8058== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8058==
==8058== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8058== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8058== by 0x10925D: main (main.c:169)
==8058==
==8058== LEAK SUMMARY:
==8058== definitely lost: 0 bytes in 0 blocks
==8058== indirectly lost: 0 bytes in 0 blocks
==8058== possibly lost: 0 bytes in 0 blocks
==8058== still reachable: 72 bytes in 1 blocks
==8058== suppressed: 0 bytes in 0 blocks
==8058==
==8058== For counts of detected and suppressed errors, rerun with: -v
==8058== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8064==
==8064== HEAP SUMMARY:
==8064== in use at exit: 72 bytes in 1 blocks
==8064== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8064==
==8064== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8064== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8064== by 0x10925D: main (main.c:169)
==8064==
==8064== LEAK SUMMARY:
==8064== definitely lost: 0 bytes in 0 blocks
==8064== indirectly lost: 0 bytes in 0 blocks
==8064== possibly lost: 0 bytes in 0 blocks
==8064== still reachable: 72 bytes in 1 blocks
==8064== suppressed: 0 bytes in 0 blocks
==8064==
==8064== For counts of detected and suppressed errors, rerun with: -v
==8064== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8060==
==8060== HEAP SUMMARY:
==8060== in use at exit: 72 bytes in 1 blocks
==8060== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8060==
==8060== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8060== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8060== by 0x10925D: main (main.c:169)
==8060==
==8060== LEAK SUMMARY:
==8060== definitely lost: 0 bytes in 0 blocks
==8060== indirectly lost: 0 bytes in 0 blocks
==8060== possibly lost: 0 bytes in 0 blocks
==8060== still reachable: 72 bytes in 1 blocks
==8060== suppressed: 0 bytes in 0 blocks
==8060==
==8060== For counts of detected and suppressed errors, rerun with: -v
==8060== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8065==
==8065== HEAP SUMMARY:
==8065== in use at exit: 72 bytes in 1 blocks
==8065== total heap usage: 1 allocs, 0 frees, 72 bytes allocated
==8065==
==8065== 72 bytes in 1 blocks are still reachable in loss record 1 of 1
==8065== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8065== by 0x10925D: main (main.c:169)
==8065==
==8065== LEAK SUMMARY:
==8065== definitely lost: 0 bytes in 0 blocks
==8065== indirectly lost: 0 bytes in 0 blocks
==8065== possibly lost: 0 bytes in 0 blocks
==8065== still reachable: 72 bytes in 1 blocks
==8065== suppressed: 0 bytes in 0 blocks
==8065==
==8065== For counts of detected and suppressed errors, rerun with: -v
==8065== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==8056==
==8056== HEAP SUMMARY:
==8056== in use at exit: 0 bytes in 0 blocks
==8056== total heap usage: 1 allocs, 1 frees, 72 bytes allocated
==8056==
==8056== All heap blocks were freed -- no leaks are possible
==8056==
==8056== For counts of detected and suppressed errors, rerun with: -v
==8056== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I tried freeing the PID array in the forked processes too but it still gives the same error.
This is not a complete answer, but it addresses some concerns.
First, the pid array memory block is being allocated with the wrong size based on a multiple of sizeof(pid_t *) when it should be the same multiple of sizeof(pid_t). That is a harmless waste of memory if sizeof(pid_t *) is greater than sizeof(pid_t), but would be a buffer overrun in the unlike case that sizeof(pid_t *) is less than sizeof(pid_t).
Second, the child processes do not free the pid array memory block.
Third, the child processes loop through all the elements of the pid array memory block looking for pid[i] == 0. I believe this is the child process trying to find its own index. However, the pid array memory block has not been fully initialized in the child process fork, so there could be more than one element with the value 0. Besides, there is no need for the child process to use the pid array at all if all it needs is its index number which it can determine at the time of the fork().
The version below fixes those issues, but I don't know if it fixes the Valgrind errors.
pid_t *pid;
//...globals & prototypes
int main(int argc, char *argv[])
{
int cid; // child index
//... Input parsing
// Create actor process=========================================
pid = malloc((_N + _V + _C + 1) * sizeof(pid_t));
for (cid = 0; xid < _N + _V + _C + 1; cid++)
{
pid[cid] = fork();
if (pid[cid] == 0)
{
free(pid);
break;
}
}
// ======================================== Create actor process
// Parent process ====================================================
if (parent_pid == getpid())
{
// Wait for all the childeren=====================================
for (int i = 0; i < _N + _V + _C + 1 || exit_requested != 0; i++)
{
int status;
if (waitpid(pid[i], &status, 0) == -1)
{
errExit("waitpid");
}
}
// =====================================Wait for all the childeren
// Free resources
free(pid);
//.. destroy semaphores
shm_unlink(SHARED_LINK);
}
// Child processes ===================================================
else
{
if (cid >= 0 && cid < _N)
{
producer(_I, shared_data, cid);
}
else if (cid >= _N && cid < _N + _V)
{
mid_consumer(shared_data, cid - _N);
}
else if (cid >= _N + _V && cid < _N + _V + _C)
{
end_consumer(shared_data, cid - _N - _V);
}
}
// ===================================================================
return 0;
}

C valgrind memory leakage

Hi my Valgrind shows me memory error but I cant find it.
==18608== HEAP SUMMARY:
==18608== in use at exit: 88 bytes in 1 blocks
==18608== total heap usage: 4 allocs, 3 frees, 2,220 bytes allocated
==18608==
==18608== Searching for pointers to 1 not-freed blocks
==18608== Checked 53,708 bytes
==18608==
==18608== 88 bytes in 1 blocks are definitely lost in loss record 1 of 1
==18608== at 0x402D17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==18608== by 0x8
0485BF: pmalloc (in auf)
==18608== by 0x8048680: main (in auf)
==18608==
==18608== LEAK SUMMARY:
==18608== definitely lost: 88 bytes in 1 blocks
==18608== indirectly lost: 0 bytes in 0 blocks
==18608== possibly lost: 0 bytes in 0 blocks
==18608== still reachable: 0 bytes in 0 blocks
==18608== suppressed: 0 bytes in 0 blocks
==18608==
==18608== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==18608== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
You allocate two different int *s; you don't free the first resource but you free the second one without doing anything with it:
print_prim(pmalloc(n), laenge);
free(pmalloc(laenge));
To free the first resource properly, you would do something like this:
int *p = pmalloc(n);
print_prim(p, laenge);
free(p);

C pthread_create causing memory leak

I have a multi-threaded application which uses joinable threads.
In order to create the threads (which are in total nthreads workers+1 additional thread) I use a regular call to pthread_create.
However, when I try to debug memory leaks, I get a x bytes in y blocks are possibly lost in loss record z of w error, caused by the pthread_create calls.
Here is the part of the code of the program relevant to the issue :
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
int main(){
int i=0;
int nthreads=8;
pthread_t tid_w[nthreads+1];
if( pthread_create(&tid_w[0], NULL, dispatcher, (void*) (size_t) i)<0){
perror("Creating dispatcher thread");
return -1;
}
for(i=1; i<nthreads+1; i++){
if( pthread_create(&tid_w[i], NULL, worker, (void*) (size_t) i)<0){
perror("Creating worker thread");
return -1;
}
}
// thread joining
for(i=0; i<nthreads+1; i++){
if( pthread_join(tid_w[i], NULL)<0){
perror("Joining thread");
return -1;
}
}
return 0;
}
This is the output of valgrind (3.11)
==14418==
==14418== HEAP SUMMARY:
==14418== in use at exit: 14,496 bytes in 21 blocks
==14418== total heap usage: 25 allocs, 4 frees, 15,724 bytes allocated
==14418==
==14418== 560 bytes in 1 blocks are possibly lost in loss record 12 of 14
==14418== at 0x4C2DB95: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14418== by 0x40134C4: allocate_dtv (dl-tls.c:322)
==14418== by 0x40134C4: _dl_allocate_tls (dl-tls.c:544)
==14418== by 0x4E400D2: allocate_stack (allocatestack.c:588)
==14418== by 0x4E400D2: pthread_create##GLIBC_2.2.5 (pthread_create.c:537)
==14418== by 0x4018AE: main (chatty.c:132)
==14418==
==14418== 4,480 bytes in 8 blocks are possibly lost in loss record 13 of 14
==14418== at 0x4C2DB95: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14418== by 0x40134C4: allocate_dtv (dl-tls.c:322)
==14418== by 0x40134C4: _dl_allocate_tls (dl-tls.c:544)
==14418== by 0x4E400D2: allocate_stack (allocatestack.c:588)
==14418== by 0x4E400D2: pthread_create##GLIBC_2.2.5 (pthread_create.c:537)
==14418== by 0x401909: main (chatty.c:138)
==14418==
==14418== LEAK SUMMARY:
==14418== definitely lost: 0 bytes in 0 blocks
==14418== indirectly lost: 0 bytes in 0 blocks
==14418== possibly lost: 5,040 bytes in 9 blocks
==14418== still reachable: 9,456 bytes in 12 blocks
==14418== suppressed: 0 bytes in 0 blocks
==14418== Reachable blocks (those to which a pointer was found) are not shown.
==14418== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==14418==
==14418== For counts of detected and suppressed errors, rerun with: -v
==14418== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Line numbers might not match because I have removed a few socket-related parts from the code.
I also have read a lot about pthread_create causing memory leaks but it seems like the issue presents itself when in use of detached threads, which is not my case.
Any idea on how to solve the issue?

Memory Leak in C free()

I'm running valgrind and it's telling me that I need to free something and I'm not sure where I would do that. It specifically points to this line "toInsert->value = linkedlist->copy(element);
Where would I run free and on what data?
"
void linkedlist_append(LinkedList *linkedlist, void *element) {
ListNode *toInsert = (ListNode*)malloc(sizeof(ListNode));
toInsert->value = linkedlist->copy(element);
toInsert->next = NULL;
ListNode *last = linkedlist->head;
if (last==NULL)
linkedlist->head = toInsert;
else{
while(last-> next !=NULL){
last = last->next;
}
last->next = toInsert;
}
linkedlist->size++;
}
Output from Valgrind:
> ^C==30515==
==30515== HEAP SUMMARY:
==30515== in use at exit: 287 bytes in 47 blocks
==30515== total heap usage: 95 allocs, 1,038 frees, 2,159 bytes allocated
==30515==
==30515== 247 bytes in 46 blocks are definitely lost in loss record 2 of 2
==30515== at 0x4C28C20: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30515== by 0x4011AC: string_copy (string_fns.c:27)
==30515== by 0x4012CE: linkedlist_append (linkedlist.c:87)
==30515== by 0x4017BD: add_file (tester.c:194)
==30515== by 0x400FE1: main (tester.c:136)
==30515==
==30515== LEAK SUMMARY:
==30515== definitely lost: 247 bytes in 46 blocks
==30515== indirectly lost: 0 bytes in 0 blocks
==30515== possibly lost: 0 bytes in 0 blocks
==30515== still reachable: 40 bytes in 1 blocks
==30515== suppressed: 0 bytes in 0 blocks
==30515== Reachable blocks (those to which a pointer was found) are not shown.
==30515== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==30515==
==30515== For counts of detected and suppressed errors, rerun with: -v
==30515== ERROR SUMMARY: 2200 errors from 10 contexts (suppressed: 0 from 0)
Valgrind is pointing you to the location of a malloc that is never freed. Before you terminate your program, you will need to iterate through the list an free all its elements.

Valgrind showing memory leak for printf and unused blocks

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
char *str = malloc(sizeof(char)*5);
str = strcpy(str, "test");
printf("%s\n", str);
free(str);
return 0;
}
When I use Valgrind on my Mac (OS X, 10.9.5) I get the following message:
==77215== HEAP SUMMARY:
==77215== in use at exit: 29,211 bytes in 374 blocks
==77215== total heap usage: 451 allocs, 77 frees, 35,160 bytes allocated
==77215==
==77215== 4,096 bytes in 1 blocks are still reachable in loss record 76 of 76
==77215== at 0x66CB: malloc (in /usr/local/Cellar/valgrind/3.10.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==77215== by 0x182855: __smakebuf (in /usr/lib/system/libsystem_c.dylib)
==77215== by 0x197217: __swsetup (in /usr/lib/system/libsystem_c.dylib)
==77215== by 0x1B0158: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==77215== by 0x1B06AF: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==77215== by 0x187B29: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==77215== by 0x18596F: printf (in /usr/lib/system/libsystem_c.dylib)
==77215== by 0x100000F2B: main (test.c:8)
==77215==
==77215== LEAK SUMMARY:
==77215== definitely lost: 0 bytes in 0 blocks
==77215== indirectly lost: 0 bytes in 0 blocks
==77215== possibly lost: 0 bytes in 0 blocks
==77215== still reachable: 4,096 bytes in 1 blocks
==77215== suppressed: 25,115 bytes in 373 blocks
==77215==
==77215== For counts of detected and suppressed errors, rerun with: -v
==77215== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 15)
Does printf allocate memory by itself? If I remove the printf I only get the following:
==77237== HEAP SUMMARY:
==77237== in use at exit: 25,115 bytes in 373 blocks
==77237== total heap usage: 450 allocs, 77 frees, 31,064 bytes allocated
==77237==
==77237== LEAK SUMMARY:
==77237== definitely lost: 0 bytes in 0 blocks
==77237== indirectly lost: 0 bytes in 0 blocks
==77237== possibly lost: 0 bytes in 0 blocks
==77237== still reachable: 0 bytes in 0 blocks
==77237== suppressed: 25,115 bytes in 373 blocks
==77237==
==77237== For counts of detected and suppressed errors, rerun with: -v
==77237== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 15)
Where does the 373 blocks come from?
Until the Valgrind team prioritizes OS X, you can safely assume that it will not give correct results on Apple systems running OS X versions newer than 10.7.
On my Mavericks (10.9.5) machine, I still get the following warning from Valgrind (3.9.0)
WARNING: Support on MacOS 10.8/10.9 is experimental and mostly broken.
WARNING: Expect incorrect results, assertions and crashes.
WARNING: In particular, Memcheck on 32-bit programs will fail to
WARNING: detect any errors associated with heap-allocated data.
For what it's worth, Valgrind 3.10.0 shows no leaks on my Debian Jessie installation.
It isn't telling you that there is a leak:
==77215== LEAK SUMMARY:
==77215== definitely lost: 0 bytes in 0 blocks
==77215== indirectly lost: 0 bytes in 0 blocks
==77215== possibly lost: 0 bytes in 0 blocks
==77215== still reachable: 4,096 bytes in 1 blocks
==77215== suppressed: 25,115 bytes in 373 blocks
it's telling you that there is a block which is still reachable; whether or not there is a leak is dependent on your definition of 'leak'. What it does mean is that there is a pointer to the block somewhere.
Refer to Still Reachable Leak detected by Valgrind for more information.

Resources