Codeguard findet kein Memory leak!



  • Hallo,

    BCB6 hat unter ..\Examples\Codeguard das Projekt buggy.bpr mitgeliefert. In dem Beispiel findet sich das folgende Konstrukt

    WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
    //..
    
    //memory leak -- allocated and never unallocated
    TStringList *sl = new TStringList;                       //Zeile #58
    sl->Add("Hello there");                                  //Zeile #59
    
    return 0;
    }
    

    Leider erkennt Codeguard genau diesen Fehler nicht.
    Hat jemand eine Erklärung?

    In der CGL-Datei finde hierzu keine entsprechende Fehlermeldung. Keine Fehlermeldung für die Zeilen buggy.cpp#58 bzw. buggy.cpp#59.
    (Linkereinstellung: Projekt-Optionen-Linker: dynamische RTL verwenden: ->aus):

    Wie kann man solche Speicherlecks sonst noch aufspüren?



  • Zumindest, wenn es sich um eigenen Code handelt, den man gerade verfasst, dann braucht man solche Leaks in der Regel nicht aufzuspüren, wenn man sie gar nicht erst entstehen lässt. Also zu jedem new direkt das passende delete schreiben (oder zum [m,c,re]alloc das free), dann sollte sowas gar nicht passieren...



  • Hallo,

    den Codeguard hast du in den Projektoptionen auch aktiviert?
    Ansonsten kann es aber auch sein, dass Codeguard gerade mal wieder nicht funktioniert, ich kann mich dunkel daran erinnern, dass das in meinem BCB6 sporadisch so war. Der zeigte ohne erkennbaren Grund eben genau solche Leaks manchmal nicht an. 😕

    Der Codeguard im BDS 2006 hat diese Macken nicht mehr...



  • @Freiheit und @_matze, Danke für Eure Antwort.

    @Freiheit schrieb:

    den Codeguard hast du in den Projektoptionen auch aktiviert?

    ja, war überall ein Häkchen dran, hätte also funktionieren müssen!

    Im gleichen Zusammenhang mit Codeguard noch eine Frage zu einem Projekt:
    wie unten erkennbar wird new 24x, delete aber nur 19x aufgerufen

    Bedeutet das, dass ich hier ein Speicherleck habe? Oder gibt es eine andere Begründung für die ungleiche Anzahl?

    Codeguard erzeugte die folgende CGL-Datei, soweit erkennbar ohne Fehlermeldung:

    Functions called:
    fflush (8 times)
    delete[] (4 times)
    new[] (4 times)
    vsnprintf (28 times)
    memset (19 times)
    delete (19 times) <=========
    free (7 times)
    memmove (6 times)
    new (24 times) <==========
    calloc (1 times)
    strlen (246 times)
    realloc (1 times)
    strdup (1 times)
    malloc (4 times)
    memcpy (2 times)
    Resource types used:
    object array (4 allocs, 4 max)
    object (24 allocs, 21 max)
    memory block (7 allocs, 7 max)
    Modules used:
    00400000 11/20/2008 00:41:10
    ..\Project1.exe



  • Hallo,

    Ja, war überall ein Häkchen dran, hätte also funktionieren müssen!

    Dann ist es der von mir bereits beschriebene Bug, dass es halt manchmal nicht funktioniert...

    Bedeutet das, dass ich hier ein Speicherleck habe? Oder gibt es eine andere Begründung für die ungleiche Anzahl?

    Nicht unbedingt, das sind nur Statistiken. Zusammen mit der Tatsache, dass Codeguard im BCB6 das von dir eingangs erwähnte Speicherleck nicht findet, würde ich nicht mehr viel auf seine Aussage geben. Davon abgesehen finde ich diese Abweichungen der Anzahl an aufgerufenen new und delete auch in allen Logs, die ich jetzt in meinen Projekten durchgesehen habe. Ich möchte jetzt nicht über die Aussage dieser Statistik spekulieren, aber IMHO kannst/solltest du daraus nicht auf Speicherlecks schließen.

    Angesehen davon: Bei einem Speicherleck würde der Codeguard so eine Meldung ins Log schreiben:
    Error 00001. 0x300010 (Thread 0x1700):
    Resource leak: The memory block (0x10FC510) was never freed

    The memory block (0x010FC510) [size: 28 bytes] was allocated with SysGetMem
    Call Tree:
    0x004E42E2(=app.exe:0x01:0E32E2) system.pas#2648
    0x005E3FAE(=app.exe:0x01:1E2FAE) IdComponent.pas#185
    0x0060F919(=app.exe:0x01:20E919)
    0x0060FAEF(=app.exe:0x01:20EAEF)

    ------------------------------------------



  • Hallo @Freiheit,
    dank Dir für Deine Einschätzung 👍
    Zum Codeguard muß ich sagen, dass die ein oder andere Erklärung anhand eines Beispiels sicher nicht geschadet hätte. Aber das IMHO (->was immer das auch heißt, so ähnlich wie "foobar" oder?) generell ein Problem bei Programmiersprachen. Die wichtigen Details stehen in keinem Handbuch. Die muß man sich um 10 Ecken von überall her bei den Leuten aus der Nase ziehen um endlich dann das zu wissen, worauf es ankommt. 🙂



  • _matze schrieb:

    Zumindest, wenn es sich um eigenen Code handelt, den man gerade verfasst, dann braucht man solche Leaks in der Regel nicht aufzuspüren, wenn man sie gar nicht erst entstehen lässt. Also zu jedem new direkt das passende delete schreiben (oder zum [m,c,re]alloc das free), dann sollte sowas gar nicht passieren...

    👎
    Wenn schon, dann richtig.

    Manuelles new/delete verursacht ein Leck, wann immer eine Exception geworfen wird. Und das ist nur einer der Gründe, lieber RAII zu benutzen.

    Eine gute Richtlinie wäre, niemals delete im eigenen Code benutzen und stattdessen immer auf einen situationsspezifischen Smart-Pointer zurückzugreifen, es sei denn, eine der folgenden Ausnahmen tritt ein:

    • In der Implementation eines Smart-Pointers oder Allokators darf delete natürlich auftauchen. (Allerdings ist es höchst ratsam, die aus der Standard-Library und aus Boost zu benutzen, anstatt selbst welche zu schreiben.)
    • Das entsprechende Objekt ist in festen Besitzverhältnissen. Das ist z.B. für Komponenten der Fall, denen ein Owner übergeben wird.

    Mehr Ausnahmen fallen mir gegenwärtig nicht ein; falls jemand eine kennt, trage er sie nach.

    Geeignete Smart-Pointer:

    Der Codeguard im BDS 2006 hat diese Macken nicht mehr...

    Mein C++Builder 2006 reproduziert das Problem.



  • Hallo,

    Mein C++Builder 2006 reproduziert das Problem.

    Merkwürdig, "mein" BDS 2006 haut mir das Leak um die Ohren... 😕



  • Freiheit schrieb:

    Merkwürdig, "mein" BDS 2006 haut mir das Leak um die Ohren... 😕

    Die Ursache scheinen die Laufzeit-Packages zu sein. Deaktiviere ich diese, so beklagt sich CodeGuard auch in diesem Falle.

    Das dürfte auch das Problem in C++Builder 6 lösen: deaktiviere die Laufzeitpackages, dann meldet CodeGuard auch Speicherlecks von Delphi-Klassen.

    (Daß CodeGuard sich so verhält, hängt vermutlich damit zusammen, daß die Speicherfreigabe nach der Destruktion von Delphi-Klassen in System.pas, bei der Verwendung von Laufzeitpackages also in rtl\d{,3}.bpl erfolgt, und CodeGuard Aufrufe aus Packages und DLLs nicht überprüft.)


Log in to reply