Valgrind is a legitimate example of a "possibly lost" byte

I saw valgrind classify memory leaks by:

  • definitely lost
  • indirectly lost
  • possibly lost
  • still available
  • crushed

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

The documentation says : " possibly lost means that your program is flowing in memory if you are not doing unusual things with pointers that could cause them to point to the middle of the selected block, see the user manual for some possible reasons"

Can I, for example, learn the example of "doing unusual things with pointers that could lead them to the middle of the selected block"?

I mean an example where “possibly lost” can be ignored, although it is reported by valgrind. An example where using pointers makes valgrind complain, but at the same time using pointers in this way is somehow legal

thanks

+7
source share
3 answers

Some examples of the fact that the documentation has different libraries that have their own allocators and for which the returned memory is not a direct pointer returned by the main OS allocator (malloc / sbrk), but a pointer after the offset. Consider, for example, a allocator that received some additional memory and stored meta-information (maybe type information for a garbage collector ...). The distribution and release process will 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 keeps track of memory, it remembers the original pointer that was returned by malloc , and this pointer is not stored anywhere in the program. But this does not mean that the memory has leaked, it means that the pointer is not directly accessible in the program. In particular, memory still contains the returned pointer, and deallocate can be called to release it, but valgrind does not see the original returned pointer in the place (char*)memory - sizeof(metadata_t) anywhere in the program and warns.

+7
source
 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); } 
+5
source
 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 this looks very interesting, I ran the code and dropped 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 states that leaks are not possible. Did I miss something?

+2
source

All Articles