2012-07-31 10 views
7

ho visto che valgrind classifica perdite di memoria in:Valgrind legittimo "probabilmente perso" Byte esempio

  • definitivamente perso
  • indirettamente perso
  • forse perso
  • ancora raggiungibile
  • soppresse

Ho appena corretto una perdita in cui il "possibilmente perso" era il problema principale.

Il documentation says: "forse perso significa che il programma perde la memoria, a meno che non si sta facendo cose insolite con i puntatori che potrebbero causare loro di puntare nel bel mezzo di un blocco allocato, vedere il manuale dell'utente per qualche possibile causa sindrome "

potrei conoscere un esempio di" fare cose insolite con i puntatori che potrebbero causare loro di puntare nel bel mezzo di un blocco allocato "?

Intendo un esempio in cui "possibilmente perso" può essere ignorato anche se viene segnalato da valgrind. Un esempio in cui l'uso di puntatori rende valgrind si lamentano, ma allo stesso tempo l'uso dei puntatori in questo modo è in qualche modo legittima

Grazie

risposta

7

Alcuni esempi di ciò che la documentazione sono diverse librerie che hanno i propri allocatori e per i quali la memoria restituita non è direttamente il puntatore restituito dall'allocatore OS sottostante (malloc/sbrk), ma un puntatore dopo un offset. Si consideri, ad esempio, un allocatore che ha ottenuto memoria extra e informazioni meta memorizzate (magari digitare informazioni per un garbage collector ...). Il processo di allocazione e deallocazione sarebbe simile a:

void* allocate(size_t size) { 
    metainfo_t *m = (metainfo_t*) malloc(size + sizeof(metainfo)); 
    m->data = some_value; 
    return (void*)(m+1);   // [1] 
} 
void deallocate(void* p) { 
    metainfo_t *m = ((metainfo_t*)p) - 1; 
    // use data 
} 
void * memory = allocate(10); 

Quando valgrind sta rintracciando la memoria, ricorda il puntatore originale che è stato restituito da malloc, e che il puntatore non viene memorizzata in qualsiasi parte del programma. Ma ciò non significa che la memoria sia trapelata, significa solo che il puntatore non è direttamente disponibile nel programma. In particolare, memory mantiene ancora il puntatore restituito e deallocate può essere chiamato per rilasciarlo, ma valgrind non vede il puntatore restituito originale nella posizione (char*)memory - sizeof(metadata_t) in qualsiasi parte del programma e avvisa.

5
char *p = malloc(100); 
if (p != 0) 
{ 
    p += 50; 
    /* at this point, no pointer points to the start of the allocated memory */ 
    /* however, it is still accessible */ 
    for (int i = -50; i != 50; i++) 
     p[i] = 1; 
    free (p - 50); 
} 
2
char *p = malloc(100); 
if (p != 0) 
{ 
    p += 50; 
    /* at this point, no pointer points to the start of the allocated memory */ 
    /* however, it is still accessible */ 
    for (int i = -50; i != 50; i++) 
     p[i] = 1; 
    free (p - 50); 
} 

Dal momento che sembra molto interessante, ho eseguito il codice e lo valgrind. Il risultato è il seguente.

[email protected]:~$ valgrind test 
==14735== Memcheck, a memory error detector 
==14735== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. 
==14735== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info 
==14735== Command: test 
==14735== 
==14735== 
==14735== HEAP SUMMARY: 
==14735==  in use at exit: 0 bytes in 0 blocks 
==14735== total heap usage: 32 allocs, 32 frees, 2,017 bytes allocated 
==14735== 
==14735== All heap blocks were freed -- no leaks are possible 
==14735== 
==14735== For counts of detected and suppressed errors, rerun with: -v 
==14735== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6) 

Dice che non ci sono perdite. Mi sto perdendo qualcosa?

+0

Si prega di inserire commenti come commenti, non come risposte. StackOverflow notifica agli utenti commenti sulle risposte, ma non (e non dovrebbe) notifica agli utenti di altri utenti che rispondono anche alla stessa domanda. Detto questo ... – hvd

+0

... il codice finisce per liberare la memoria, quindi Valgrind non lo vede.Il punto che stavo facendo era che se il programma termina prima di raggiungere 'libero' (o semplicemente non è affatto libero), e' p' rimane impostato, allora valgrind considererà la memoria allocata eventualmente persa. Durante il test, in modo che 'p' rimanga impostato, potrebbe anche essere necessario rendere' p' un globale. – hvd

+0

Ho provato a postarlo come commenti, ma i commenti hanno il numero di limiti di caratteri. Mi dispiace per quello – jaeyong