Вот пример «определенно потеряно» или «все еще достижимо»:
#include <stdio.h>
#include <stdlib.h>
void *p;
int main()
{
p = malloc(10);
p = malloc(100);
void *m = malloc(50);
return 0;
}
В этом коде происходит следующее:
- 10 байт выделяются и указатель на эту память назначается глобальному
p
. - 100 байт выделяются, а указатель на эту память назначается глобальному
p
. Это перезаписывает значение указателя, указывающее на 10 выделенных байтов, и на него больше нет ссылки. Таким образом, память «определенно потеряна». - 50 байт выделяются, и указатель на эту память назначается локальному
m
. main
возвращает, что приводит к времени жизни m
до конца. В результате не сохраняется ссылка на указатель памяти на 50 байт, так что память «определенно потеряна». - Указатель значения указателя на 100 байт все еще находится в глобальном
p
, поэтому процедуры очистки, такие как поскольку те, которые вызываются atexit
или другими методами c компилятора, могут очистить эту память. Таким образом, он «все еще доступен».
При запуске valgrind с этим кодом он выводит следующее:
==60822== Memcheck, a memory error detector
==60822== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==60822== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==60822== Command: ./x1
==60822==
==60822==
==60822== HEAP SUMMARY:
==60822== in use at exit: 160 bytes in 3 blocks
==60822== total heap usage: 3 allocs, 0 frees, 160 bytes allocated
==60822==
==60822== LEAK SUMMARY:
==60822== definitely lost: 60 bytes in 2 blocks
==60822== indirectly lost: 0 bytes in 0 blocks
==60822== possibly lost: 0 bytes in 0 blocks
==60822== still reachable: 100 bytes in 1 blocks
==60822== suppressed: 0 bytes in 0 blocks
==60822== Rerun with --leak-check=full to see details of leaked memory
==60822==
==60822== For counts of detected and suppressed errors, rerun with: -v
==60822== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Что согласуется с описанием выше.
Итак, чтобы подвести итог, память «все еще доступна», если указатель на нее хранится либо в переменной области видимости файла, либо на него указывает любая «все еще доступная» память. В противном случае он будет утерян.