Memcheck is a memory error detector. It can detect the following problems that are common in C and C++ programs.
Accessing memory you shouldn't, e.g. overrunning and underrunning heap blocks, overrunning the top of the stack, and accessing memory after it has been freed.
Using undefined values, i.e. values that have not been initialised, or that have been derived from other undefined values.
Incorrect freeing of heap memory, such as double-freeing heap blocks, or mismatched use of
memcpyand related functions.
Passing a fishy (presumably negative) value to the
sizeparameter of a memory allocation function.
Memory leak detection
- The pointer might have originally been a start-pointer and have been moved along deliberately (or not deliberately) by the program. In particular, this can happen if your program uses tagged pointers, i.e. if it uses the bottom one, two or three bits of a pointer, which are normally always zero due to alignment, in order to store extra information.
- It might be a random junk value in memory, entirely unrelated, just a coincidence.
- It might be a pointer to the inner char array of a C++
std::string. For example, some compilers add 3 words at the beginning of the std::string to store the length, the capacity and a reference count before the memory containing the array of characters. They return a pointer just after these 3 words, pointing at the char array.
- Some code might allocate a block of memory, and use the first 8 bytes to store (block size – 8) as a 64bit number.
- It might be a pointer to an array of C++ objects (which possess destructors) allocated with
new. In this case, some compilers store a "magic cookie" containing the array length at the start of the allocated block, and return a pointer to just past that magic cookie, i.e. an interior-pointer. See this page for more information.
- It might be a pointer to an inner part of a C++ object using multiple inheritance.
With that in mind, consider the nine possible cases described by the following figure.
Pointer chain AAA Leak Case BBB Leak Case ------------- ------------- ------------- (1) RRR ------------> BBB DR (2) RRR ---> AAA ---> BBB DR IR (3) RRR BBB DL (4) RRR AAA ---> BBB DL IL (5) RRR ------?-----> BBB (y)DR, (n)DL (6) RRR ---> AAA -?-> BBB DR (y)IR, (n)DL (7) RRR -?-> AAA ---> BBB (y)DR, (n)DL (y)IR, (n)IL (8) RRR -?-> AAA -?-> BBB (y)DR, (n)DL (y,y)IR, (n,y)IL, (_,n)DL (9) RRR AAA -?-> BBB DL (y)IL, (n)DL Pointer chain legend: - RRR: a root set node or DR block - AAA, BBB: heap blocks - --->: a start-pointer - -?->: an interior-pointer Leak Case legend: - DR: Directly reachable - IR: Indirectly reachable - DL: Directly lost - IL: Indirectly lost - (y)XY: it's XY if the interior-pointer is a real pointer - (n)XY: it's XY if the interior-pointer is not a real pointer - (_)XY: it's XY in either case
Leak Message Case
Every possible case can be reduced to one of the above nine. Memcheck merges some of these cases in its output, resulting in the following four leak kinds.
- "Still reachable". This covers cases 1 and 2 (for the BBB blocks) above. A start-pointer or chain of start-pointers to the block is found. Since the block is still pointed at, the programmer could, at least in principle, have freed it before program exit. "Still reachable" blocks are very common and arguably not a problem. So, by default, Memcheck won't report such blocks individually.
- "Definitely lost". This covers case 3 (for the BBB blocks) above. This means that no pointer to the block can be found. The block is classified as "lost", because the programmer could not possibly have freed it at program exit, since no pointer to it exists. This is likely a symptom of having lost the pointer at some earlier point in the program. Such cases should be fixed by the programmer.
- "Indirectly lost". This covers cases 4 and 9 (for the BBB blocks) above. This means that the block is lost, not because there are no pointers to it, but rather because all the blocks that point to it are themselves lost. For example, if you have a binary tree and the root node is lost, all its children nodes will be indirectly lost. Because the problem will disappear if the definitely lost block that caused the indirect leak is fixed, Memcheck won't report such blocks individually by default.
- "Possibly lost". This covers cases 5–8 (for the BBB blocks) above. This means that a chain of one or more pointers to the block has been found, but at least one of the pointers is an interior-pointer. This could just be a random value in memory that happens to point into a block, and so you shouldn't consider this ok unless you know you have interior-pointers.