delete void*



  • Ich hab mir ein (älteres) Opensource Program heruntergeladen, und wollte ein paar Bugs fixen.
    Unter anderem habe ich festgestellt, dass Memoryleaks auftreten.

    Ich hab stark folgenden Code in Verdacht:

    void* AnArray[50];
    
    ...
    long* Var1 = new long;
    AnArray[0] = Var1;
    ...
    CString* Var2 = new CString;
    AnArray[1] = Var2;
    ...
    
    delete AnArray[0];
    delete AnArray[1];
    ... //(die Anzahl der gespeicherten Zeiger ist bekannt)
    

    Es werden auch noch weitere Typen gespeichert (z.B. BYTE*, DWORD*,...)

    Ich bezweifle stark, dass "delete" jeweils die Variablen hier korrekt aufräumt?

    Falls er den Speicher nicht korrekt freigibt, kann man da irgendetwas direkt beim "delete" machen (der Code ist zu komplex und zu lang, als dass ich Lust hätte, jede Stelle zu ändern)? Mir schwebte so was wie

    if (dynamic_cast<long*>(AnArray[0]) != NULL)
       delete dynamic_cast<long*>(AnArray[0];
    

    vor, was ja allerdings nicht funktioniert.

    PS: Ich benutzte VS2008, der Code wurde ursprünglich für VS2003 (glaube ich) geschrieben.



  • Warum macht man sowas?

    In C++ gibt es viel bessere Varianten als void* . Wenn man unbedingt ein Array aus unterschiedlichen Typen braucht - was an sich schon fragwürdig genug ist - gibt es immer noch typsichere und selbstaufräumende Konstrukte wie boost::any .

    Deine delete s räumen wie du denkst nicht auf. Genauer gesagt geben sie zwar den Speicher, auf den der Zeiger unmittelbar zeigt, frei. Da der Compiler aber den Typ dahinter nicht kennt, kann er keinen Destruktor aufrufen. Gerade bei Klassen mit dynamischer Speicherverwaltung entsteht dadurch mit grosser Wahrscheinlichkeit ein Memory Leak.

    Mit dem aktuellen Design bleibt dir nichts anderes übrig, als jeden Eintrag in den Typen zu casten ( static_cast ), mit dem er erstellt wurde, und anschliessend delete darauf anzuwenden. Zumindest bei den Klassen. Bei den PODs wie int spielt das keine grosse Rolle, da dort sowieso kein Destruktoraufruf stattfindet.

    Trotzdem würde ich das Design grundsätzlich nochmals überdenken...

    Sorry für die vielen Edits, hab immer noch was gefunden, das ich ergänzen könnte... 😉



  • Nexus schrieb:

    Warum macht man sowas?

    In C++ gibt es viel bessere Varianten als void* . Wenn man unbedingt ein Array aus unterschiedlichen Typen braucht - was an sich schon fragwürdig genug ist - gibt es immer noch typsichere und selbstaufräumende Konstrukte wie boost::any .

    Der Code wird wohl so alt sein, das er vor boost::any Zeiten geschrieben worden ist 😃


Anmelden zum Antworten