2012-01-31 13 views
15

Se vogliamo controllare le perdite di memoria in un programma C++, possiamo sovraccaricare gli operatori new e delete per tenere traccia della memoria che è stato assegnato. E se volessimo verificare la presenza di perdite in un programma C? Poiché non v'è alcun operatore sovraccarico in C, possiamo sovrascrivere il puntatore malloc funzione di intercettare chiamate a malloc e monitorare allocazione di memoria? C'è un modo più semplice senza utilizzare alcuna utilità esterna? Fornire del codice in quanto non ho familiarità con i puntatori del metodo di sovrascrittura.Rilevare perdite di memoria nei programmi C?

Nota: Vorrei fare questo senza alcun utility esterne per la pratica.

+4

cosa c'è che non va con Valgrind? –

+0

@MitchWheat ho detto che non posso usare qualsiasi utilità esterna –

+0

Bene, se questo è per l'apprendimento, si può imparare come valgrind lo fa ... –

risposta

35

Come suggerito, esistono già strumenti eccellenti come Valgrind per farlo.

Ulteriori:

vorrei fare questo senza alcun utility esterne per la pratica
Questo è interessante e sono sicuro che sarebbe stato appagante,
È possibile utilizzare macro trucco per rilevare ad esempio l'utilizzo della memoria e errori di perdita, in effetti scrivere il proprio rilevatore di perdite pulito. Dovresti essere in grado di farlo finché hai una singola allocazione e una funzione di deallocazione nel tuo progetto.

#define malloc(X) my_malloc(X, __FILE__, __LINE__, __FUNCTION__) 

void* my_malloc(size_t size, const char *file, int line, const char *func) 
{ 

    void *p = malloc(size); 
    printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size); 

    /*Link List functionality goes in here*/ 

    return p; 
} 

Si mantiene un elenco collegato di indirizzi assegnati con il file e il numero di riga da cui è stato assegnato. Si aggiorna la lista dei collegamenti con voci nel proprio malloc.

Come sopra è possibile scrivere un'implementazione per free, in cui si controlla che le voci dell'indirizzo vengano richieste per essere liberate rispetto all'elenco collegato. Se non c'è una voce corrispondente è un errore di utilizzo e puoi segnalarlo così.

Alla fine del programma si stampa o si scrive il contenuto dell'elenco collegato in un file di registro. Se non ci sono perdite, l'elenco collegato non deve contenere voci, ma se ci sono alcune perdite, il file di registro fornisce la posizione esatta in cui è stata allocata la memoria.

Si noti che nell'utilizzo di questo trucco macro, si perde il controllo di tipo che offre le funzioni, ma è un piccolo trucchetto che uso molte volte.

Spero che questo aiuti e tutto il meglio :)

+0

Questo è un approccio decisamente interessante, posso semplicemente aggiungere la dimensione a qualche contatore quando viene richiamato malloc e quindi sottrarre le dimensioni quando viene invocato libero? –

+3

Si potrebbe, ma questo non sta per darvi la granularità che si potrebbe desiderare. Quindi hai perso 2000 byte. Era un'allocazione di 2000 byte o 10 200 byte di allocazioni? Un elenco ti farebbe risparmiare un sacco di tempo per passare un registro cercando di far combaciare le cose. – Duck

+0

@MikeG: Sì, come ha giustamente detto Duck, l'elenco collegato offre la flessibilità e la funzionalità per determinare con precisione le allocazioni di errore. –

10

Valgrind è quello che ti serve.

Ricordo di aver letto primo capitolo di Algorithms in a Nutshell che ha parlato di questo, anche se non ha incluso il codice. Appena aggiunto nel caso in cui lo trovi interessante.

poiché non v'è nessun operatore sovraccarico in c possiamo over-write malloc punto la funzione di intercettare le chiamate a malloc e monitorare la memoria allocazione

In realtà, è possibile. GIve LD_PRELOAD una lettura.

+0

So come usare Valgrind voglio solo implementarlo io stesso –

+1

@MikeG: Questo è come se tu abbia un cancro e tu "conosci gli ospedali, ma vuoi provare a curarlo da solo per la pratica". –

+5

@KerrekSB: Non c'è niente di sbagliato nel giocarci, è sicuramente una grande esperienza di apprendimento. A proposito, valgrind è il migliore in un ambiente di progetto in tempo reale, ma devo ammettere che è stato un buon apprendimento per me quando l'ho fatto a lungo tempo fa. –

4

Oltre a @ di Als risposta che avvolgere le chiamate nel codice sorgente, se si sta utilizzando GNU ld, si può avere il linker avvolgere tutte le chiamate (presumibilmente a malloc, realloc, calloc e free) al tempo di collegamento, indipendentemente da dove provengono. Quindi scrivi __wrap_malloc ecc. E puoi chiamare la funzione originale con, ad esempio, __real_malloc.

Vedi --wrap=symbol in http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html

Non so come funziona con le chiamate da librerie condivise. Immagino che non sia così.

1

Ecco come è possibile modificare malloc, ganci liberi: Hooks for Malloc

+1

cambiare i collegamenti ipertestuali. dovresti descrivere la soluzione che hai trovato sul link –

1

Usa mallinfo funzionare ha funzionato per me su Xilinx Zynq BareMetal utilizzando Xilinx SDK gcc. Ho provato con perdita di memoria intenzionale - non ho idea del perché ma i risultati di Google sono stati incredibilmente terribili nel trovare questa soluzione per diffondere la parola per aiutare altri sviluppatori!