2011-01-24 11 views
8

Todo el código de prueba está contenida en main.cpp como sigue:¿Por qué Valgrind no detecta una pérdida de memoria en mi programa de "prueba"?

#include <iostream> 

using std::cout; 
using std::endl; 

void f(int i) { 
    int* pi = new int; 

    *pi = i; 

    std::cout << "*pi = " << *pi << std::endl; 
} 

int main(int argc, char *argv[]) { 
    int i = 0; 

    while (i < 10000) { 
     f(i); 
     ++i; 
    } 

    return 0; 
} 

compilo sin optimizaciones -O0 (de un proyecto de Eclipse Qt) con:

g++ -c -pipe -O0 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -Irelease -o release/main.o main.cpp 

entonces enlace como sigue:

g++ -Wl,-O0 -o test release/main.o -L/usr/lib -lQtGui -lQtCore -lpthread 

que lance el ejecutable a través valgrind y obtener el siguiente resultado:

laptop:~/workspace/test$ valgrind --leak-check=yes test 
==3939== Memcheck, a memory error detector 
==3939== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==3939== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info 
==3939== Command: test 
==3939== 
==3939== 
==3939== HEAP SUMMARY: 
==3939==  in use at exit: 0 bytes in 0 blocks 
==3939== total heap usage: 1,387 allocs, 1,387 frees, 64,394 bytes allocated 
==3939== 
==3939== All heap blocks were freed -- no leaks are possible 
==3939== 
==3939== For counts of detected and suppressed errors, rerun with: -v 
==3939== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 8) 

creo valgrind debe reportar una fuga de memoria en lugar de que no son posibles fugas debido a la memoria del montón asignado en las llamadas a new int

EDIT: Se cambió el código de usar std :: cout en lugar de qDebug() con el mismo resultado

Si compilación y enlace para el mismo código (de un proyecto de Eclipse CDT) sin dependencias Qt, valgrind detecta la fuga:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp" 

g++ -o"test2" ./main.o 

==4604== HEAP SUMMARY: 
==4604==  in use at exit: 40,000 bytes in 10,000 blocks 
==4604== total heap usage: 10,000 allocs, 0 frees, 40,000 bytes allocated 
==4604== 
==4604== 40,000 bytes in 10,000 blocks are definitely lost in loss record 1 of 1 
==4604== at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255) 
==4604== by 0x8048756: f(int) (main.cpp:7) 
==4604== by 0x80487BB: main (main.cpp:18) 
==4604== 
==4604== LEAK SUMMARY: 
==4604== definitely lost: 40,000 bytes in 10,000 blocks 
==4604== indirectly lost: 0 bytes in 0 blocks 
==4604==  possibly lost: 0 bytes in 0 blocks 
==4604== still reachable: 0 bytes in 0 blocks 
==4604==   suppressed: 0 bytes in 0 blocks 
==4604== 
==4604== For counts of detected and suppressed errors, rerun with: -v 
==4604== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 19 from 8) 

estoy u cantar Kubuntu 10.04 32 bit y haber intentado ambas compilaciones Debug and Release, ¿qué estoy haciendo mal o por qué valgrind no informa una fuga de memoria cuando se enlaza con Qt?

+0

¿Puede ser que el compilador haya eliminado ese código porque considera que no tiene ningún efecto? – sharptooth

+0

@sharptooth: No lo creo porque en el modo de depuración qDebug escribe en stdout, que es un efecto secundario que debería evitar la eliminación del compilador? También intenté con 'std :: cout' en lugar de con' qDebug' (las llamadas a se eliminan en la versión) y obtuve el mismo resultado. ¿Obtienes el mismo resultado que yo? –

+0

No he probado ese código. Sin embargo, a mí me parece que la fuga debe ser informada y puedo suponer dos razones para que no se informe: optimización del compilador o algo especial con la implementación del montón que interfiere con valgrind. – sharptooth

Respuesta

17

La razón de que esto sucedió es que la llamada a:

valgrind --leak-check=yes test 

estaba ejecutando valgrind en/usr/bin/test, que es un programa integrado que comprueba los tipos de archivos y los compara valores, todo lo que necesitaba era:

valgrind --leak-check=yes ./test 
+0

+1 buena captura !! –

0

he sustituido qDebug() con std :: cout:

==2426== HEAP SUMMARY: 
==2426==  in use at exit: 40,000 bytes in 10,000 blocks 
==2426== total heap usage: 10,000 allocs, 0 frees, 40,000 bytes allocated 
==2426== 
==2426== LEAK SUMMARY: 
==2426== definitely lost: 39,996 bytes in 9,999 blocks 
+0

Nada cambió cuando utilicé el código y las opciones del compilador. Tal vez es culpa de Eclipse. – knivil

0

Probablemente su compilador eliminar ese código en la optimización, tratar de compilar con -O0 (sin opciones de optimización).

Como comentario, con debian lenny con O2, se detecta la fuga:

==20547== LEAK SUMMARY: 
==20547== definitely lost: 40,000 bytes in 10,000 blocks. 
==20547==  possibly lost: 0 bytes in 0 blocks. 
==20547== still reachable: 516 bytes in 7 blocks. 
==20547==   suppressed: 0 bytes in 0 blocks. 
==20547== Rerun with --leak-check=full to see details of leaked memory. 

El compilador:

gcc version 4.3.2 (Debian 4.3.2-1.1) 
+0

@peter I enlace contra qt. –

Cuestiones relacionadas