11

I saw that valgrind classifies memory leaks into:

  • definitely lost
  • indirectly lost
  • possibly lost
  • still reachable
  • suppressed

I just fixed a leak where the "possibly lost" was the main problem.

The documentation says: "possibly lost means your program is leaking memory, unless you're doing unusual things with pointers that could cause them to point into the middle of an allocated block; see the user manual for some possible causes"

May I please know an example of "doing unusual things with pointers that could cause them to point into the middle of an allocated block" ?

I mean an example where "possibly lost" can be ignored although it is reported by valgrind. An example in which the use of pointers makes valgrind complain but at the same time the use of the pointers in that way is somehow legitimate

Thank you

wsdookadr
  • 2,584
  • 1
  • 21
  • 44

3 Answers3

9

Some examples of what the documentation are different libraries that have their own allocators and for which the memory returned is not directly the pointer returned by the underlying OS allocator (malloc/sbrk), but a pointer after an offset. Consider for example, an allocator that obtained some extra memory and stored meta information (maybe type information for a garbage collector...). The process of allocation and deallocation would be similar to:

void* allocate( size_t size ) {
   metainfo_t *m = (metainfo_t*) malloc( size + sizeof(metainfo) );
   m->data = some_value;
   return (void*)(m+1);          // [1]
}
void deallocate( void* p ) {
   metainfo_t *m = ((metainfo_t*)p) - 1;
   // use data
}
void * memory = allocate(10);

When valgrind is tracking the memory, it remembers the original pointer that was returned by malloc, and that pointer is not stored anywhere in the program. But that does not mean that the memory has been leaked, it only means that the pointer is not directly available in the program. In particular memory still holds the returned pointer, and deallocate can be called to release it, but valgrind does not see the original returned pointer at location (char*)memory - sizeof(metadata_t) anywhere in the program and warns.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
5
char *p = malloc(100);
if (p != 0)
{
    p += 50;
    /* at this point, no pointer points to the start of the allocated memory */
    /* however, it is still accessible */
    for (int i = -50; i != 50; i++)
        p[i] = 1;
    free (p - 50);
}
2
char *p = malloc(100);
if (p != 0)
{
    p += 50;
    /* at this point, no pointer points to the start of the allocated memory */
    /* however, it is still accessible */
    for (int i = -50; i != 50; i++)
        p[i] = 1;
    free (p - 50);
}

Since it looks very interesting, I did run the code and valgrind it. The result is the following.

yjaeyong@carbon:~$ valgrind test
==14735== Memcheck, a memory error detector
==14735== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==14735== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==14735== Command: test
==14735== 
==14735== 
==14735== HEAP SUMMARY:
==14735==     in use at exit: 0 bytes in 0 blocks
==14735==   total heap usage: 32 allocs, 32 frees, 2,017 bytes allocated
==14735== 
==14735== All heap blocks were freed -- no leaks are possible
==14735== 
==14735== For counts of detected and suppressed errors, rerun with: -v
==14735== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6)

It says no leaks are possible. Am I missing anything?

jaeyong
  • 8,951
  • 14
  • 50
  • 63
  • Please put comments as comments, not as answers. StackOverflow notifies users of comments on their answers, but does not (and should not) notify users of other users who also answer the same question. That said... –  Jul 31 '12 at 14:17
  • ...the code ends up freeing the memory, so valgrind doesn't see it. The point I was making was that if the program exits before reaching the `free` (or simply doesn't free at all), and `p` remains set, then valgrind will consider the allocated memory possibly lost. While testing, in order for `p` to remain set, you may also need to make `p` a global. –  Jul 31 '12 at 14:20
  • I tried to post it as comments, but the comments has number of character limitation. Sorry about that. – jaeyong Aug 01 '12 at 00:42
  • > if the program exits before reaching the free (or simply doesn't free at all), and p remains set, then valgrind will consider the allocated memory possibly lost. Oh, I see – jaeyong Aug 01 '12 at 01:25