Valgrind informa que definitivamente perdí la memoria si salgo de main con return 0; , pero informa que todavía se puede acceder a la memoria si salgo de main con exit(0); .
prueba-alcanzable.c:
#include <stdlib.h> int main() { void *data = malloc(256); exit(0); }prueba-perdida.c:
#include <stdlib.h> int main() { void *data = malloc(256); return 0; }Comportamiento:
$ gcc test-reachable.c -o test-reachable $ valgrind --leak-check=yes ./test-reachable ==7696== Memcheck, a memory error detector ==7696== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==7696== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==7696== Command: ./test-reachable ==7696== ==7696== ==7696== HEAP SUMMARY: ==7696== in use at exit: 256 bytes in 1 blocks ==7696== total heap usage: 1 allocs, 0 frees, 256 bytes allocated ==7696== ==7696== LEAK SUMMARY: ==7696== definitely lost: 0 bytes in 0 blocks ==7696== indirectly lost: 0 bytes in 0 blocks ==7696== possibly lost: 0 bytes in 0 blocks ==7696== still reachable: 256 bytes in 1 blocks ==7696== suppressed: 0 bytes in 0 blocks ==7696== Reachable blocks (those to which a pointer was found) are not shown. ==7696== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==7696== ==7696== For counts of detected and suppressed errors, rerun with: -v ==7696== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) $ gcc test-lost.c -o test-lost $ valgrind --leak-check=yes ./test-lost ==7774== Memcheck, a memory error detector ==7774== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==7774== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==7774== Command: ./test-lost ==7774== ==7774== ==7774== HEAP SUMMARY: ==7774== in use at exit: 256 bytes in 1 blocks ==7774== total heap usage: 1 allocs, 0 frees, 256 bytes allocated ==7774== ==7774== 256 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==7774== at 0x4C2C080: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7774== by 0x40051C: main (in /tmp/test-lost) ==7774== ==7774== LEAK SUMMARY: ==7774== definitely lost: 256 bytes in 1 blocks ==7774== indirectly lost: 0 bytes in 0 blocks ==7774== possibly lost: 0 bytes in 0 blocks ==7774== still reachable: 0 bytes in 0 blocks ==7774== suppressed: 0 bytes in 0 blocks ==7774== ==7774== For counts of detected and suppressed errors, rerun with: -v ==7774== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)¿No deberían comportarse igual?
¿No deberían comportarse igual?
No.
En test-reachable.c, los data de la variable de pila hacen referencia a la memoria en el momento de la salida del programa, por lo que todavía es accesible, mientras que en test-lost.c ya no se hace referencia a la memoria porque la función main ya ha devuelto, la referencia ya no existe, la memoria se ha perdido definitivamente.
En C++, cuando se llama a return in main() , se llamará a los destructores para objetos de ámbito local, mientras que si se llama a exit() , no se llamará a ningún destructor para objetos de ámbito local. Creo que esto es similar en C con respecto a los objetos asignados en la pila.
Eso probablemente explica por qué en el caso de return , la memoria no liberada se trata como definitivamente perdida y en el caso de exit(0) , la memoria se informa como aún accesible.