Rheinwerk Computing :: C von A bis Z - 27.2 Memory Leaks (Speicherlecks) (2024)

27.2 Memory Leaks (Speicherlecks) Rheinwerk Computing :: C von A bis Z - 27.2 Memory Leaks (Speicherlecks) (3)

Wie bei Buffer Overflows sind auch Memory Leaks in den meisten Fällen durch Programmierfehler zu erklären. Der erste Verdacht, es könnte sich bei Memory Leaks um Hardwareprobleme handeln, täuscht.

Ein Memory Leak entsteht, wenn ein Programm dynamisch Speicher alloziert (malloc(), realloc(), ...) und diese Speicherressourcen nicht mehr an das System zurückgibt (mittels free()). Es steht nicht unendlich viel Speicher vom Heap dafür zur Verfügung.

Programme wie das jetzt folgende erzeugen keine Probleme, wenn der Speicher nicht mehr an den Heap zurückgegeben wird:

/* mleak1.c */#include <stdio.h>#include <stdlib.h>#include <string.h>int main(void) { char *p; p = malloc(sizeof("Hallo Welt\n")); if(NULL == p) { fprintf(stderr, "Abbruch: Speichermangel !!\n"); return EXIT_FAILURE; } strcpy(p, "Hallo Welt\n"); printf("%s",p); return EXIT_SUCCESS;}

Hier bekommt der Heap seinen Speicher bei Beendigung des Programms sofort wieder zurück.

Was ist aber mit Programmen, die dauerhaft im Einsatz sein müssen? Ein gutes Beispiel sind Telefongesellschaften, die jedes laufende, eingehende und ausgehende Gespräch nach dem FIFO-Prinzip auf dem Heap ablegen und ständig für diese Datensätze Speicher auf dem Heap allozieren bzw. für ältere Datensätze wieder freigeben müssen.

Ein (stupides) Beispiel:

/* mleak2.c */#include <stdio.h>#include <stdlib.h>int main(void) { char *p; while(p = malloc(64000)) { if(NULL == p) { fprintf(stderr, "Speicherplatzmangel!!\n"); return EXIT_FAILURE; } /* Tu was mit dem reservierten Speicher. */ } return EXIT_SUCCESS;}

Dieses Programm wird wohl eine Weile ohne Probleme laufen. Aber je länger das Programm läuft, umso mehr Speicher benötigt es vom Heap. Dies wird sich auf Dauer schlecht auf die Performance des Systems auswirken. Denn der Heap ist ja nicht nur für ein Programm allein da. Die anderen Programme, die ebenfalls Ressourcen benötigen, werden immer langsamer. Am Ende bleibt einem nichts anderes mehr übrig, als das System neu zu starten (abhängig vom Betriebssystem und der Art der Anwendung).

Meistens ist das Programm aber längst fertiggestellt, wenn ein Speicherleck gefunden wird. Dann kann guter Rat teuer werden, wenn Sie sich nicht auskennen.

Eine primitive Möglichkeit, sofern Sie im Besitz des Quellcodes sind, ist es, sogenannte Wrapper-Makros für speicherallozierte und speicherfreigebende Funktionen zu schreiben, beispielsweise für die malloc()-Funktion:

#define malloc(size) \ malloc(size);\ printf("malloc in Zeile %ld der Datei %s (%ld Bytes) \n"\ ,__LINE__,__FILE__, size);\ count_malloc++;

Bei Verwendung der malloc()-Funktion im Programm wird jetzt jeweils eine Ausgabe auf dem Bildschirm erzeugt, die anzeigt, in welcher Zeile und in welchem Programm die Funktion malloc() vorkommt und wie viel Speicher sie verwendet. Außerdem wird die Verwendung von malloc() mitgezählt.

Dasselbe wird anschließend auch mit der Funktion free() gemacht. Die Anzahl der gezählten malloc()- und free()-Aufrufe wird am Ende in eine Datei namens DEBUG_FILE geschrieben.

/* mem_check.h */#ifndef MEM_CHECK_H#define MEM_CHECK_H#define DEBUG_FILE "Debug"static int count_malloc=0;static int count_free =0;FILE *f;#define malloc(size) \ malloc(size);\ printf("malloc in Zeile %d der Datei %s (%d Bytes) \n"\ ,__LINE__,__FILE__, size);\ count_malloc++;#define free(x)\ free(x); \ x=NULL;\ printf("free in Zeile %d der Datei %s\n", __LINE__,__FILE__);\ count_free++;#define return EXIT_SUCCESS; \ f=fopen(DEBUG_FILE, "w");\ fprintf(f, "Anzahl malloc : %d\n",count_malloc);\ fprintf(f, "Anzahl free : %d\n",count_free);\ fclose(f);\ printf("Datei : %s erstellt\n", DEBUG_FILE);\ return EXIT_SUCCESS;#endif

Hier wurde eine Headerdatei namens mem_check.h erstellt, mit der alle Aufrufe von malloc() und free() auf dem Bildschirm ausgeben werden. Sie erfahren dadurch, in welcher Datei und welcher Zeile sich ein Aufruf dieser Funktion befindet. Außerdem wird auch die Anzahl der malloc()- und free()-Aufrufe mitgezählt. Sind mehr malloc()-Aufrufe als free()-Aufrufe vorhanden, wurde auf jeden Fall ein Speicherleck im Programm gefunden. Hier sehen Sie ein Listing zum Testen:

/* use_mem_check.c */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "mem_check.h"int main(void) { char *p; p = malloc(sizeof("Hallo Welt\n")); if(NULL == p) { fprintf(stderr, "Speichermangel!!!\n"); return EXIT_FAILURE; } strcpy(p, "Hallo Welt\n"); printf("%s",p); malloc(1024); free(p); return EXIT_SUCCESS;}

In der Praxis und bei größeren Projekten ist diese Version, Memory Leaks aufzuspüren, nur bedingt geeignet. Mit dem Makro return 0 habe ich es mir allzu leicht gemacht. Dies setzt nämlich voraus, dass ein Programm auch damit beendet wird. Oft haben Sie es aber mit dauerhaft laufenden Programmen zu tun.

Genauso sieht es mit der Zuordnung des allozierten und freigegebenen Speichers aus. Welches malloc() gehört zu welchem free()? Aber das Prinzip dürfte Ihnen klar geworden sein. Wenn Sie Fehler wie Memory Leaks finden wollen, haben Sie notfalls mit Wrapper-Makros eine gute Möglichkeit.

Meistens werden Sie schon eher auf eines der mittlerweile vielen Tools oder auf eine der Bibliotheken zurückgreifen, die zur Erkennung von Memory Leaks programmiert wurden.

27.2.1 Bibliotheken und Tools zu Memory Leaks Rheinwerk Computing :: C von A bis Z - 27.2 Memory Leaks (Speicherlecks) (5)

Es gibt mittlerweile eine unüberschaubare Menge von solchen Debugging-Tools. Daher folgt hier ein kleiner Überblick mit Angabe der Bezugsquellen. Meistens finden Sie dabei auf diesen Webseiten gleich die Dokumentation für die Anwendung.

ccmalloc

Bezugsquelle: http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/

ccmalloc wird mit dem C/C++-Programm verlinkt und gibt nach Beendigung des Programms einen Bericht über Memory Leaks aus. ccmalloc ist nicht geeignet, um festzustellen, ob versucht wurde, aus illegalen Speicherbereichen zu lesen.

dbmalloc

Bezugsquelle:ftp://ftp.digital.com/pub/usenet/comp.sources.misc/volume32/dbmalloc/

dbmalloc ist in einer kommerziellen und einer kostenlosen Version erhältlich. Besondere Merkmale von dbmalloc sind:

  • Funktionsfluss, Datei und Zeileninformationen werden mit angegeben.
  • Gibt Adressen zurück (hilfreich zusammen mit Debuggern).
  • Grenzbereichsüberprüfung
  • Ausgabe auf die Standard-Fehlerausgabe
  • Findet Memory Leaks.

Generell wird dbmalloc, wie die meisten anderen Memory-Leak-Tools zu einem Programm hinzugelinkt. Sie müssen also im Besitz des Quellcodes sein, um diesen neu zu übersetzen. Eine gute Anleitung in deutscher Sprache zu dieser Bibliothek finden Sie unter der URL http://www.c-handbuch.org/.

mpatrol

Bezugsquelle: http://www.cbmamiga.demon.co.uk/mpatrol/

mpatrol ist ein leistungsfähiges Tool zum Auffinden von Memory Leaks, das sich leider auf die Performance des Programms negativ auswirkt. Folgende Funktionsmerkmale stehen Ihnen dabei zur Verfügung:

  • Ein Abbild des Stacks wird bei einem Fehler angezeigt.
  • Datei- und Zeilen-Informationen werden mit ausgegeben.
  • Es ist kompatibel zu dmalloc, dbmalloc, insure und purify.
  • Es ist nicht unbedingt erforderlich, neu zu übersetzen, um seine Programme mit mpatrol zu testen.
  • mpatrol findet alle denkbaren Fehler auf dem Heap. Fehler auf dem Stack werden nicht gefunden.

Um ein Programm mit mpatrol zu testen, ist genau wie bei den meisten anderen Tools ein Überschreiben der speicheranfordernden und freigebenden Funktionsaufrufe notwendig. Bei mpatrol können Sie dies auf zwei Arten machen: Entweder Sie linken das Programm zu der statischen oder dynamischen Bibliothek oder Sie binden diese später durch einen Aufruf von

mpatrol --dynamc ./testprog -i file

dynamisch mit in das Programm ein. Die letzte Möglichkeit funktioniert allerdings nur, wenn das Programm schon dynamisch zur Standard-C-Bibliothek übersetzt wurde, und selbst dann nur auf einigen wenigen Systemen, die diesen Befehl unterstützen. Für eine deutsche Dokumentation sei auch hier wieder auf die Webseite http://www.c-handbuch.org/ verwiesen.

Es gibt außer diesen hier genannten Tools noch eine Reihe weiterer sehr guter Tools zum Auffinden von Memory Leaks. Einen guten Überblick können Sie sich auf der Seite http://www.cs.colorado.edu/~zorn/MallocDebug.html verschaffen.


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

Rheinwerk Computing :: C von A bis Z - 27.2 Memory Leaks (Speicherlecks) (2024)
Top Articles
Latest Posts
Article information

Author: Mrs. Angelic Larkin

Last Updated:

Views: 6370

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Mrs. Angelic Larkin

Birthday: 1992-06-28

Address: Apt. 413 8275 Mueller Overpass, South Magnolia, IA 99527-6023

Phone: +6824704719725

Job: District Real-Estate Facilitator

Hobby: Letterboxing, Vacation, Poi, Homebrewing, Mountain biking, Slacklining, Cabaret

Introduction: My name is Mrs. Angelic Larkin, I am a cute, charming, funny, determined, inexpensive, joyous, cheerful person who loves writing and wants to share my knowledge and understanding with you.