Come rilevare perdite di memoria in C/C++ con Valgrind

Come Rilevare Perdite Di Memoria In C C Con Valgrind



Valgrind è uno strumento ampiamente utilizzato per eseguire il debug e profilare i programmi software scritti principalmente in C, C++ e altri linguaggi. Aiuta gli sviluppatori a rilevare perdite di memoria, rintracciare gli errori di accesso alla memoria e profilare l'esecuzione dei loro programmi.

Quando esegui un programma con Valgrind, questo strumenta dinamicamente l'eseguibile del programma, consentendogli di monitorare l'utilizzo della memoria e il comportamento di esecuzione del programma.

Perdite di memoria in C++

È importante notare che Valgrind è progettato principalmente per programmi C e C++ e potrebbe non funzionare in modo altrettanto efficace con altri linguaggi o in tutti gli scenari. Inoltre, l'esecuzione di un programma sotto Valgrind può rallentarne significativamente l'esecuzione, quindi viene spesso utilizzato durante lo sviluppo e il debug piuttosto che negli ambienti di produzione.







Quando una memoria creata dinamicamente non viene rilasciata correttamente, può causare perdite di memoria in C/C++ che prosciugheranno lentamente le risorse di memoria disponibili. Ciò può comportare un consumo eccessivo di memoria e una riduzione delle prestazioni del programma.



Installazione Valgrid

Per installare Valgrind su un sistema Linux, apri un terminale e aggiorna i repository dei pacchetti utilizzando il gestore pacchetti specifico per la tua distribuzione Linux. Il seguente comando funziona per i sistemi basati su Ubuntu e Debian:



$ sudo aggiornamento adeguato

Utilizza il gestore pacchetti per installare Valgrind. Ancora una volta, il comando può variare a seconda della distribuzione Linux. Utilizzare il seguente comando per i sistemi basati su Ubuntu e Debian:





$ sudo adatto installare porta elettorale

Quando richiesto, inserisci la password utente e premi 'Invio'. Tieni presente che il tuo account utente necessita di privilegi amministrativi per installare il software. Il gestore pacchetti scarica e installa Valgrind insieme a tutte le dipendenze necessarie. Il processo potrebbe richiedere alcuni minuti.



Al termine del processo di installazione, puoi confermare la corretta installazione di Valgrind eseguendo il seguente comando come passaggio di verifica:

$ porta elettorale --versione

Questo comando visualizza le informazioni sulla versione di Valgrind se è installato correttamente.

Questo è tutto! Valgrind dovrebbe ora essere installato sul tuo sistema Linux e puoi usarlo per analizzare ed eseguire il debug dei tuoi programmi C/C++ per perdite di memoria e altri problemi.

Creazione di un file in Ubuntu

Per iniziare a lavorare sul programma, dobbiamo prima creare un file in Ubuntu. Per la creazione dei file utilizziamo l'editor di testo nano. Quindi, scriviamo il comando sul terminale come segue:

$ nano file1

Qui nano è il nome dell'editor di testo che viene eseguito. L'argomento 'file1' rappresenta il nome del file che intendi aprire o creare utilizzando l'editor di testo nano. Nano apre il file per la modifica se esiste già; in caso contrario genera un nuovo file con il nome fornito. Poiché non disponiamo di un file di questo tipo, crea un nuovo documento con il nome 'file1'.

Una volta eseguito il comando, si aprirà l'editor nano, fornendoti un'area vuota per inserire o modificare il contenuto del file 'file1'. Puoi iniziare a digitare o incollare il contenuto esistente nell'editor.

Ora che tutti i prerequisiti sono stati soddisfatti, creiamo alcuni esempi per utilizzare Valgrind per rilevare le perdite di memoria nei programmi C++.

Esempio 1:

Il primo esempio che forniamo mostra un semplice esempio di allocazione dinamica della memoria utilizzando la funzione 'malloc' dalla libreria in C.

#include

int principale ( )

{

car * UN = malloc ( 102 ) ;

ritorno 0 ;

}

Ecco una ripartizione del codice:

Per prima cosa includiamo il file di intestazione della libreria standard che fornisce funzioni come malloc per l'allocazione e la deallocazione dinamica della memoria.

La riga int main() dichiara la funzione main. Quindi, il char *a = malloc(102); dichiara una variabile puntatore “a” di tipo char* (puntatore a char). Utilizza la funzione 'malloc' per allocare dinamicamente la memoria per un array di 102 elementi di carattere (102 byte in totale). La dimensione dell'allocazione della memoria, espressa in byte, viene inviata come input alla funzione malloc e restituisce in output un puntatore al blocco di memoria appena creato. Al puntatore char* 'a' viene assegnato questo valore del puntatore. Infine, il “return 0;” indica la fine della funzione principale.

In breve, questo codice alloca dinamicamente la memoria per un array di 102 elementi di carattere utilizzando 'malloc' e assegna l'indirizzo di memoria al puntatore 'a'. Tuttavia, tieni presente che il codice non utilizza né manipola in alcun modo la memoria allocata e non include la deallocazione della memoria utilizzando free.

Quando eseguiamo questo programma tramite Valgrind con l'opzione “–leak-check=full”, esegue un controllo della perdita di memoria e fornisce un rapporto di output.

Il report di output prodotto da Valgrid è il seguente:

Esempio 2:

Per cominciare con questa illustrazione, creiamo prima un file “test2” utilizzando l’editor di testo nano come spiegato in precedenza scrivendo il comando:

$ nano prova2

Ora scriviamo un programma C++ per verificare se c'è qualche perdita di memoria usando Valgrind:

#include

#include

#include

const int a_s = 3000 ;

int principale ( ) {

int * ia = malloc ( taglia di ( int ) * COME ) ;

per ( int io = 0 ; io < COME; i++ ) {

Esso [ io ] = io;

}

srand ( tempo ( NULLO ) ) ;

int rn = rand ( ) % COME;

printf ( 'it[%d]: %d \N ' , infatti, esso [ rn ] ) ;

ritorno 0 ;

}

Esaminiamo il programma.

Il codice include i file header necessari e definisce la variabile costante “a_s” con un valore 3000. All'interno della funzione main() viene dichiarato un puntatore “ia” di tipo int* e la memoria viene allocata dinamicamente utilizzando il metodo “malloc” funzione. L'espressione 'sizeof(int) * a_s' determina la memoria totale richiesta per memorizzare il numero di numeri interi 'a_s'. Tutti gli elementi dell'array 'ia' vengono inizializzati dal ciclo 'for' con il valore di indice corrispondente. Ad esempio, ia[0] sarà 0, ia[1] sarà 1 e così via.

Il generatore di numeri casuali viene seminato utilizzando la funzione 'srand' utilizzando l'ora corrente. Ciò garantisce che il programma produca un insieme univoco di numeri interi casuali ogni volta che viene eseguito. La funzione “rand” genera un numero casuale e a “rn” viene assegnato il risultato di rand() % a_s. L'operatore modulo “%” limita l'intervallo del numero casuale tra 0 e a_s – 1 che corrisponde a un indice valido all'interno dell'array “ia”.

Infine, il programma utilizza la funzione 'printf' per stampare il valore nell'indice 'rn' selezionato casualmente dell'array 'ia', insieme all'indice corrispondente.

Quando esegui questo programma tramite Valgrind, genera il seguente report di output:

  Uno screenshot di un programma per computer Descrizione generata automaticamente

Conclusione

Abbiamo scoperto l'utilizzo dello strumento Valgrind per rilevare le perdite di memoria in un programma C++. Inizialmente viene fornita la guida all'installazione di Valgrind. Successivamente, abbiamo elaborato la creazione di un file in Ubuntu utilizzando l'editor di testo nano. Alla fine, utilizzando questi prerequisiti, abbiamo eseguito due esempi C++ per verificare le perdite di memoria al loro interno. È allegato anche il report generato da Valgrind che mostra le perdite di memoria nel file fornito.