2010-06-06 23 views
11

Welche Tipps kann ich verwenden, um Speicherlecks in meinen Anwendungen zu vermeiden? In meinem aktuellen Projekt verwende ich ein Tool "INSURE ++", das den Speicherleck findet und den Report generiert.Möglichkeiten zur Vermeidung von Memory Leaks in C/C++

Neben dem Tool gibt es eine Methode, um Speicherlecks zu identifizieren und zu überwinden.

+10

Verwenden Sie C oder C++? Die verfügbaren Lösungen sind für die beiden Sprachen ziemlich unterschiedlich. –

+0

Ich benutze C. Kannst du bitte eine Lösung für C und C++ geben – Ankur

+7

@ Ankur: Nun, eine Antwort, die für C Sinn macht, wird nicht sinnvoll für C++ und umgekehrt. Speicherverwaltung ist eines der Bits, die sich in C++ ändern. –

Antwort

9

Es gibt drei Hauptwege, dies zu tun.

Die erste ist zu Speicherlecks in erster Linie nicht erstellen. Defensive Programmiertechniken sind hier von unschätzbarem Wert. Eine Zusammenfassung dieser Probleme finden Sie unter excellent presentation oder das entsprechende Kapitel in Secure C Coding. Ich bin vertrauter mit C als C++, aber ich verstehe, dass C++ smart pointers hier nützlich sind.

Ein zweiter Ansatz statische Analyse, die versucht, Fehler in Ihrem Quellcode zu erkennen. Das Originalwerkzeug in dieser Kategorie ist fussel, das jetzt leider veraltet ist. Die besten Werkzeuge, soweit ich weiß, sind kommerziell wie coverty. Jedoch einige free tools do exist.

Der dritte Ansatz besteht darin, Speicherverluste zur Laufzeit zu erkennen, wie INSURE ++ tut. Valgrind ist hier ausgezeichnet und sehr zu empfehlen. Es kann helfen, Fehler zu finden, die Sie bereits eingeführt haben. Es ist besonders hilfreich, wenn Sie eine Testsuite mit einer guten Codeabdeckung haben.

0

Um zu vermeiden oder zu erkennen? Um zu vermeiden, zuerst zu erkennen und zu versuchen, zu verstehen, wo und warum ... Ein anderer Weg könnte die Verwendung einer GC-Bibliothek sein, wie the one described here, aber andere (vielleicht bessere) Bibliotheken können existieren.

2

Sprechen wir Tools, um Lecks zu finden, oder Wege, um sie zu vermeiden?

Für die ehemalige, die oben genannten Valgrind oder Rational Suite von IBM Tools, wenn Sie eine Lizenz dazu haben. Dr. Dobbs Compuware Bounds empfohlen, aber das war 2002.

Für die später finden Sie unter:

C++ idiom to avoid memory leaks?

http://www.cprogramming.com/tutorial/memory_debugging_parallel_inspector.html

http://scottmcpeak.com/memory-errors/

http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

1

Verwenden Sie ein Smart-Pointer, wie std::shared_ptr<t> (C++ 0x), std::tr1::shared_ptr<t> (TR1) oder boost::shared_ptr<t>. Natürlich funktioniert diese Lösung nur mit C++ - Sie in C auf eigene Faust

2

Intelligente Zeiger kann sehr hilfreich sein in der Buchhaltung von Objektlebensdauern zu automatisieren:

http://ootips.org/yonat/4dev/smart-pointers.html

Wo es möglich ist, verwenden stack allokierte Objekte innerhalb ihrer relevanten Bereiche statt neu/löschen.

Werkzeuge wie Valgrind haben etwas Overhead und können Ihre Läufe verlangsamen.Wenn Sie Ihre Codebasis und die Arten von Lecks kennen, die dazu neigen, aufzutauchen, können Sie auf bestimmte Klassen abzielen und leichtere Gewichtsprüfungen durchführen (sogar nur eine einfache Anzahl von Objekten, die Sie beim Beenden auf Null überprüfen). Diese leichtgewichtigen Überprüfungen können dann verwendet werden, um Sie zu einer umfangreicheren Valgrind-Debugging-Sitzung zu motivieren, wenn sie ausgelöst werden.

7

Für C hilft eine gute Codeorganisation. I.e. Wirf keine Aufrufe an malloc() und free() über deine Codebasis. Zentralisieren Sie sie in zwei Funktionen, dann haben Sie einen einzigen Punkt für alle Überprüfungen. Am einfachsten wäre es, die erfolgreichen Aufrufe zu zählen und beim Programmende zu prüfen, ob sie ausgeglichen sind.

static unsigned long mymem_count_alloc = 0; 
static unsigned long mymem_count_free = 0; 

void *mymem_alloc (size_t size) 
{ 
    void *p; 

    p = malloc(size); 
    if (p) 
    { 
     mymem_count_alloc++; 
    } 
    else 
     error logging/handling/signaling 

    return (p); 
} 

void mymem_free (void *p) 
{ 
    if (p) 
    { 
     free(p); 
     mymem_count_free++; 
    } 
} 

void mymem_check (void) 
{ 
    if (mymem_count_alloc != mymem_count_free) 
     error alert 
} 

Sie können dies für die verschiedenen Datenstrukturen fortsetzen. Wo immer Sie Speicher für einen String reservieren müssen, verwenden Sie mystr_alloc und mystr_free. Und so weiter. Wenn ein Leck auf diese Weise erkannt wird, können Sie es schnell eingrenzen.

+0

+1 hauptsächlich für die "Für C, hilft eine gute Code-Organisation ...". Ich persönlich würde es vorziehen, diese genaue Methode nicht zu verwenden. Ich würde opake Datenstrukturen verwenden, die die Verwendung von Funktionen zum Erstellen/Zerstören jedes bestimmten Datentyps erzwingen. Die Zählung würde in diese Datenstrukturen umschalten/Funktionen zerstören. Sie müssen Ihren Code klar dafür organisieren, da es alles zu leicht ist, um unordentlich zu werden. Dies wird ausreichen, um viele Lecks zu finden, und Valgrind ist sehr gut, wenn es darum geht, Zaunpfostenfehler in Arrays zu fangen. –

+0

Mit dieser Aussage wäre diese Methode immer noch nützlich, aber ich würde sicherlich wollen, dass die Verwendung bedingt ist: sie ersetzt malloc/free für Debug-Builds, aber malloc/free wird in Release-Builds verwendet. –

+0

@James: Ich gehe auch mit dem Create/Destroy-Ansatz. Aber dort werden immer Wrapper-Funktionen für malloc/free verwendet, die natürlich etwas anspruchsvoller sind als dieses Beispiel. Der Fehlerbehandlungsteil ist immer notwendig, und wenn etwas ** immer ** notwendig ist, wenn eine Bibliotheksfunktion aufgerufen wird, sollte sie entweder ein Teil der Funktion selbst werden oder in einen Wrapper eingefügt werden, wenn die Manipulation der Funktion nicht möglich ist in Bezug auf das DRY-Prinzip. http://stackoverflow.com/questions/1529679/how-do-you-program-safely-outside-of-a-managed-code-environment/1530581#1530581 – Secure

Verwandte Themen