So erkennen Sie Speicherlecks in C/C++ mit Valgrind

So Erkennen Sie Speicherlecks In C C Mit Valgrind



Valgrind ist ein weit verbreitetes Tool zum Debuggen und Profilieren von Softwareprogrammen, die hauptsächlich in C, C++ und anderen Sprachen geschrieben sind. Es hilft den Entwicklern, Speicherlecks zu erkennen, Speicherzugriffsfehler aufzuspüren und die Ausführung ihrer Programme zu profilieren.

Wenn Sie ein Programm unter Valgrind ausführen, wird die ausführbare Datei des Programms dynamisch instrumentiert, sodass die Speichernutzung und das Ausführungsverhalten des Programms überwacht werden können.

Speicherlecks in C++

Es ist wichtig zu beachten, dass Valgrind in erster Linie für C- und C++-Programme entwickelt wurde und möglicherweise nicht so effektiv mit anderen Sprachen oder in allen Szenarien funktioniert. Darüber hinaus kann die Ausführung eines Programms unter Valgrind die Ausführung erheblich verlangsamen, sodass es häufig während der Entwicklung und beim Debuggen und nicht in Produktionsumgebungen verwendet wird.







Wenn ein dynamisch erstellter Speicher nicht ordnungsgemäß freigegeben wird, kann es in C/C++ zu Speicherlecks kommen, die die verfügbaren Speicherressourcen langsam belasten. Dies kann zu einem übermäßigen Speicherverbrauch und einer verminderten Leistung des Programms führen.



Valgrid-Installation

Um Valgrind auf einem Linux-System zu installieren, öffnen Sie ein Terminal und aktualisieren Sie Ihre Paket-Repositorys mit dem Paketmanager, der für Ihre Linux-Distribution spezifisch ist. Der folgende Befehl funktioniert für Ubuntu- und Debian-basierte Systeme:



$ Sudo passendes Update

Verwenden Sie den Paketmanager, um Valgrind zu installieren. Auch hier kann der Befehl je nach Linux-Distribution variieren. Verwenden Sie den folgenden Befehl für Ubuntu- und Debian-basierte Systeme:





$ Sudo geeignet Installieren Wahltor

Geben Sie bei Aufforderung Ihr Benutzerpasswort ein und drücken Sie „Enter“. Beachten Sie, dass Ihr Benutzerkonto Administratorrechte benötigt, um die Software zu installieren. Der Paketmanager lädt Valgrind herunter und installiert es zusammen mit allen erforderlichen Abhängigkeiten. Der Vorgang kann einige Minuten dauern.



Nachdem der Installationsprozess abgeschlossen ist, können Sie die erfolgreiche Installation von Valgrind bestätigen, indem Sie den folgenden Befehl als Überprüfungsschritt ausführen:

$ Wahltor --Ausführung

Dieser Befehl zeigt die Versionsinformationen von Valgrind an, wenn es erfolgreich installiert wurde.

Das ist es! Valgrind sollte jetzt auf Ihrem Linux-System installiert sein und Sie können es verwenden, um Ihre C/C++-Programme auf Speicherlecks und andere Probleme zu analysieren und zu debuggen.

Erstellen einer Datei in Ubuntu

Um mit der Arbeit am Programm zu beginnen, müssen wir zunächst eine Datei in Ubuntu erstellen. Für die Dateierstellung nutzen wir den Nano-Texteditor. Also schreiben wir den Befehl wie folgt auf das Terminal:

$ Nano Datei1

Hier ist nano der Name des Texteditors, der ausgeführt wird. Das Argument „file1“ stellt den Namen der Datei dar, die Sie mit dem Nano-Texteditor öffnen oder erstellen möchten. Nano öffnet die Datei zur Bearbeitung, falls sie bereits vorhanden ist; Wenn nicht, wird eine neue Datei mit dem angegebenen Namen generiert. Da wir keine solche Datei haben, wird ein neues Dokument mit dem Namen „Datei1“ erstellt.

Sobald Sie den Befehl ausführen, wird der Nano-Editor geöffnet und bietet Ihnen eine leere Leinwand, auf der Sie den Inhalt der Datei „file1“ eingeben oder bearbeiten können. Sie können mit der Eingabe oder dem Einfügen des vorhandenen Inhalts in den Editor beginnen.

Nachdem nun alle Voraussetzungen erfüllt sind, erstellen wir einige Beispiele, um mit Valgrind Speicherlecks in C++-Programmen zu erkennen.

Beispiel 1:

Das erste von uns bereitgestellte Beispiel zeigt ein einfaches Beispiel für die dynamische Speicherzuweisung mithilfe der Funktion „malloc“ aus der Bibliothek in C.

#include

int hauptsächlich ( )

{

verkohlen * A = malloc ( 102 ) ;

zurückkehren 0 ;

}

Hier ist eine Aufschlüsselung des Codes:

Wir fügen zunächst die Standardbibliotheksheaderdatei ein, die Funktionen wie malloc für die dynamische Speicherzuweisung und -freigabe bereitstellt.

Die Zeile int main() deklariert die Hauptfunktion. Dann ist das char *a = malloc(102); deklariert eine Zeigervariable „a“ vom Typ char* (Zeiger auf char). Es verwendet die Funktion „malloc“, um den Speicher für ein Array von 102 char-Elementen (insgesamt 102 Bytes) dynamisch zuzuweisen. Die in Bytes ausgedrückte Speicherzuordnungsgröße wird als Eingabe an die malloc-Funktion gesendet und diese gibt einen Zeiger auf den frisch erstellten Speicherblock aus. Dem char*-Zeiger „a“ wird dieser Zeigerwert zugewiesen. Zu guter Letzt: „return 0;“ bedeutet das Ende der Hauptfunktion.

Kurz gesagt, dieser Code weist mithilfe von „malloc“ dynamisch den Speicher für ein Array von 102 char-Elementen zu und weist die Speicheradresse dem Zeiger „a“ zu. Beachten Sie jedoch, dass der Code den zugewiesenen Speicher in keiner Weise nutzt oder manipuliert und keine Freigabe des Speichers mithilfe von „free“ vorsieht.

Wenn wir dieses Programm über Valgrind mit der Option „–leak-check=full“ ausführen, führt es eine Speicherleckprüfung durch und stellt einen Ausgabebericht bereit.

Der von Valgrid erstellte Ausgabebericht lautet wie folgt:

Beispiel 2:

Um mit dieser Abbildung zu beginnen, erstellen wir zunächst eine „test2“-Datei mit dem Nano-Texteditor, wie zuvor erklärt, indem wir den folgenden Befehl schreiben:

$ Nano test2

Jetzt schreiben wir ein C++-Programm, um mithilfe von Valgrind zu prüfen, ob ein Speicherverlust vorliegt:

#include

#include

#include

const int a_s = 3000 ;

int main ( ) {

int * ia = malloc ( Größe von ( int ) * als ) ;

für ( int i = 0 ; ich < als; i++ ) {

Es [ ich ] = ich;

}

Sand ( Zeit ( NULL ) ) ;

int rn = rand ( ) % als;

printf ( 'es[%d]: %d \N ' , rn, es [ rn ] ) ;

zurückkehren 0 ;

}

Lassen Sie uns das Programm durchgehen.

Der Code enthält die notwendigen Header-Dateien und definiert die Konstantenvariable „a_s“ mit einem Wert von 3000. Innerhalb der Funktion main() wird ein Zeiger „ia“ vom Typ int* deklariert und der Speicher mithilfe der Funktion „malloc“ dynamisch zugewiesen. Funktion. Der Ausdruck „sizeof(int) * a_s“ bestimmt den insgesamt erforderlichen Speicher zum Speichern der Anzahl „a_s“ von Ganzzahlen. Alle Elemente des „ia“-Arrays werden durch die „for“-Schleife mit ihrem entsprechenden Indexwert initialisiert. Beispielsweise ist ia[0] 0, ia[1] 1 und so weiter.

Der Zufallszahlengenerator wird mit der Funktion „srand“ unter Verwendung der aktuellen Uhrzeit geseedt. Dadurch wird sichergestellt, dass das Programm bei jeder Ausführung einen eindeutigen Satz zufälliger Ganzzahlen erzeugt. Die Funktion „rand“ generiert eine Zufallszahl und „rn“ wird das Ergebnis von rand() % a_s zugewiesen. Der Moduloperator „%“ begrenzt den Bereich der Zufallszahl auf einen Wert zwischen 0 und a_s – 1, was einem gültigen Index innerhalb des „ia“-Arrays entspricht.

Schließlich verwendet das Programm die Funktion „printf“, um den Wert am zufällig ausgewählten Index „rn“ des Arrays „ia“ zusammen mit dem entsprechenden Index zu drucken.

Wenn Sie dieses Programm über Valgrind ausführen, wird der folgende Ausgabebericht generiert:

  Ein Screenshot einer automatisch generierten Computerprogrammbeschreibung

Abschluss

Wir haben die Verwendung des Tools Valgrind entdeckt, um Speicherlecks in einem C++-Programm zu erkennen. Zunächst wird die Installationsanleitung des Valgrind bereitgestellt. Danach haben wir die Erstellung einer Datei in Ubuntu mit dem Nano-Texteditor näher erläutert. Am Ende haben wir unter Verwendung dieser Voraussetzungen zwei C++-Beispiele ausgeführt, um die darin enthaltenen Speicherlecks zu überprüfen. Der von Valgrind generierte Bericht ist ebenfalls beigefügt, der die Speicherlecks in der bereitgestellten Datei zeigt.