Speicher-Zugrifffehler finden



  • Hallo!

    Ich habe ein kleines Problem. Und zwar habe ich ein mittlerweise relativ großes Programm entwickelt, welches mit mehreren Threads arbeitet und relativ komplex geworden ist. Da es Grafiken im Speicher bearbeitet, benutzt das Programm relativ viele direkte Speicherzugriffe (meinArray[12] = 12; oder *meinArray++ = 12;).

    Nun folgendes: Ich würde gerne, da ich die Vermutung habe, dass solche Fehler existieren, alle Speicher-Zugriffsfehler finden.

    Das heißt, Fehler, bei denen die Anwendung in nicht legale Speicherbereiche schreibt. Das Programm stürzt leider nicht immer in solchen Fällen ab.

    void main(){
        // Überlauf
        char* a = new char[ 20 ];
        a[20] = 123;
    
        // Oder ein ähnliches Problem
        *(a-1) = 123;
    }
    

    Gibt es da mit Hilfe von gdb oder ähnliche Tools mit denen man das testen kann? Das Ganze betrifft sowohl die "malloc" / "realloc" als auch die "new" Schreibweise, da ich beides benutze.

    Vielen Dank im voraus



  • erstens: void main() ist falsch - sowohl im C- als auch im C++-Standard gibt main int zurück.
    zweitens: in C++ bietet sich std::vector an, viele Implementierungen haben im op[] im Debugmodus eine Abfrage drin die dich auf solche Fehler aufmerksam macht. Daneben gibts noch weitere Vorteile, z.B. wird der Speicher automatisch freigegeben und es gibt nicht wie hier bei dir ein Speicherleck.


  • Mod

    Google mal nach valgrind. Das findet zwar nicht alles, bringt dich aber schonmal ein gewaltiges Stück weiter.

    P.S.: Mischen von malloc und new kann gefährlich sein. Du musst aufpassen, dass du nicht mit delete Sachen freigibst, die von malloc kommen und umgekehrt.



  • @pumuckl:
    Hehe, ja - das war jetzt ein on-the-fly Text für das Forum - in meiner Source habe ich int main( int argc, char **argv ) { return 0; } benutzt ^^ Und das delete fehlt auch in dem Beispiel 🙂

    Ich benutze C++ (new, new[]) für das generelle Programm (indem auch ggf. Speicherprobleme auftauchen können), aber benutze C (malloc) für die meisten Grafikoperationen. Ist also sowohl C++ als auch C.

    @SeppJ:
    Danke, ich werde mir das mal anschauen. Gebe dann Feedback wie weit ich gekommen bin.

    Für die Fehlerfindung ob ich Sachen nicht falsch freigebe habe ich mir bereits wrapper für die Funktionen (safe_malloc, safe_free z.B.) geschrieben. Die überprüfen dann auch OB es freigegeben wird - nur leider Überschreitungen nicht. Aber ich schaue mir mal Valgrind an 🙂 Danke



  • Es gibt auch noch purify (jetzt bei der IBM) davon ist eine Trial-Version verfügbar, die zwar Einschränkungen hat, aber m.W. zeitlich nicht begrenzt ist.



  • ProfEich schrieb:

    Ich benutze C++ (new, new[]) für das generelle Programm (indem auch ggf. Speicherprobleme auftauchen können), aber benutze C (malloc) für die meisten Grafikoperationen. Ist also sowohl C++ als auch C.

    Das interessiert mich jetzt. Was sind das für Grafikoperationen? Kannst du für diese nicht auch new/new[] und delete/delete[] verwenden?

    Abgesehen davon solltest du darauf achten, so wenig Speicher wie möglich manuell zu verwalten. In C++ gibt es z.B. Smart-Pointer und Container, welche wunderbar von solchen Low-Level-Operationen abstrahieren können. Wenn du diese konsequent einsetzt, gehören Memory Leaks der Vergangenheit an.



  • Nexus schrieb:

    ProfEich schrieb:

    Ich benutze C++ (new, new[]) für das generelle Programm (indem auch ggf. Speicherprobleme auftauchen können), aber benutze C (malloc) für die meisten Grafikoperationen. Ist also sowohl C++ als auch C.

    Das interessiert mich jetzt. Was sind das für Grafikoperationen? Kannst du für diese nicht auch new/new[] und delete/delete[] verwenden?

    Ich schätze mal, dass da Filter laufen werden. Auch weil er da Multithreading angetönt hat.

    @ProfEich
    Wenn du den Code ändern kannst, dann würden sich (falls du keine Container, wie vector nehmen willst) assertions anbieten, welche du dann für Release Builds komplett ausschalten kannst. Das ist allerdings dann in etwa das, was auch übliche Container machen. Der Vorteil ist halt, dass du deinen Code direkt nicht ändern musst, sondern lediglich die Abfragen einfügen.

    Ansonsten Valgrind oder auch z.B (für Windows) benutze ich gerne den Visual Leak Detector.


Anmelden zum Antworten