2010-08-21 15 views
27

¿Puedo tratar la salida de un valche de Valgrind, "posiblemente perdido" como "definitivamente perdido"?Valgrind: ¿se puede perder posiblemente ser tratado como definitivamente perdido?

Posiblemente perdido o "dudoso": se encuentra un puntero al interior del bloque. El puntero originalmente podría haber apuntado al inicio y se han movido a lo largo, o podría no estar relacionado por completo. Memcheck considera un bloque como "dudoso", porque no está claro si aún existe un puntero .

Definitivamente perdido, o "filtrado": El peor resultado es que no se puede encontrar ningún puntero al bloque. El bloque se clasifica como "filtrado", porque el programador no pudo haberlo liberado en la salida del programa , ya que no existe un puntero al mismo. Esto es probablemente un síntoma de habiendo perdido el puntero en algún punto anterior en el programa

Respuesta

45

Sí, me recomiendan para tratar posiblemente perdió tan grave como definitivamente perdió. En otras palabras, arregle su código hasta que no haya pérdidas en absoluto.

Posiblemente se pierda cuando se recorre una matriz con el mismo puntero que la sostiene. Usted sabe que puede restablecer el puntero restando el índice. Pero valgrind no puede decir si es un error de programación o si está siendo inteligente haciendo esto deliberadamente. Es por eso que te advierte.

Ejemplo

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int main(int argc, char** argv) { 
    char* s = "string"; 
    // this will allocate a new array 
    char* p = strdup(s); 
    // move the pointer into the array 
    // we know we can reset the pointer by subtracting 
    // but for valgrind the array is now lost 
    p += 1; 
    // deliberately trigger a segfault to crash the program 
    *s = 'S'; 
    // reset the pointer to the beginning of the array 
    p -= 1; 
    // properly free the memory for the array 
    free(p); 
    return 0; 
} 

Compilar

$ gcc -ggdb foo.c -o foo 

informe Valgrind

$ valgrind ./foo 
... 
==3415== Command: ./foo 
==3415== 
==3415== 
==3415== Process terminating with default action of signal 11 (SIGSEGV) 
==3415== Bad permissions for mapped region at address 0x80484E0 
==3415== at 0x804840E: main (foo.c:14) 
==3415== 
==3415== HEAP SUMMARY: 
==3415==  in use at exit: 7 bytes in 1 blocks 
==3415== total heap usage: 1 allocs, 0 frees, 7 bytes allocated 
==3415== 
==3415== LEAK SUMMARY: 
==3415== definitely lost: 0 bytes in 0 blocks 
==3415== indirectly lost: 0 bytes in 0 blocks 
==3415==  possibly lost: 7 bytes in 1 blocks 
==3415== still reachable: 0 bytes in 0 blocks 
==3415==   suppressed: 0 bytes in 0 blocks 
... 

Si se quita la línea que causa la violación de segmento continuación Valgrind informará sin memoria perdida en absoluto. Sin segfault, el puntero volverá al comienzo de la matriz y la memoria será free d correctamente.

Este es un ejemplo trivial. En un código lo suficientemente complicado, ya no es obvio que el puntero puede y volverá al comienzo del bloque de memoria. Los cambios en otra parte del código pueden hacer que el posiblemente perdido sea un definitivamente perdido. Es por eso que debe preocuparse por posiblemente perdido.

+0

gracias lesmana para una explicación más detallada. –

Cuestiones relacionadas