new und delete von pointern



  • Hallo Leute, ich weiß nicht ob diese Frage hier oder ins C-Forum gehört. Da es new/delete statt malloc()/free() verwendet versuche ich erst einmal hier.

    Ich schaffe es nicht einen Memory Leak loszuwerden. Normalerweise arbeite ich nicht mit manueller Speicherverwaltung, bin jetzt aber durch eine externe Vorgabe dazu gezwungen worden. Mein Problem ist ein Memory Leak (laut Visual Leak Detektor) im ptr_a den ich nicht loswerden kann. Das Programm hat dadurch einen völlig weltfremden fluss und landet bei

    const bool tmp = false;
    if( tmp )
    {
      // trotz false landet man hier
    }
    

    trotz false innerhalb des if blocks. Scheint so als ob ich irgendwo über den zugelassenen Bereich schreibe..

    Wo ich den Fehler "vermute":
    Ich habe die Funktion func_a() die ein Array aus einem Pointer erzeugt, der vom Sichtbarkeitsbereich weder zu func_a() noch zu func_b() gehört.

    float *ptr_a = NULL;
    void func_a( ... , &int size_a , float * &ptr_a )
    {
     ...
     size_a = // Ergebnis vieler Berechnungen
     ptra = new float[size_a];
    }
    void func_b( int size_a , float * &ptr_a )
    {
      // ... nutze den Pointer A
      delete [] ptr_a;
    }
    

    Dieses Array wird in func_b() gelöscht. Darf ich das, wenn diese wie in den Funktionssignaturen als Referenz übergeben werden oder muss ich es im selben Sichtbarkeitsbereich löschen wo es erzeugt wurde?

    Danke



  • const bool tmp = false; 
    if( tmp ) 
    { 
      // trotz false landet man hier 
    }
    

    Wenn ich mich nicht irre, dann dürften das die meisten neueren Compiler wegoptimieren.



  • ptra = new float[size_a];
    

    Wo kommt denn ptra her?



  • Sone schrieb:

    const bool tmp = false; 
    if( tmp ) 
    { 
      // trotz false landet man hier 
    }
    

    Wenn ich mich nicht irre, dann dürften das die meisten neueren Compiler wegoptimieren.

    Nicht im Debugmodus. Es nur ein Beispiel, dass es bei einem konstanten bool false im if Block landet, was an sich (mMn) für eine Speicherkorrumpierung spricht.

    Sone schrieb:

    float * &ptr_a )
    

    Willst du das wirklich so haben?

    Sicherlich nicht!

    Ich muss einen Pointer aus der höchsten Sichtbarkeitsebene an die Funktionen reichen und sehe im Moment keine andere Lösung.

    Der Programmfluss ist so:

    1. Pointer wird in außerhalb von func_a() erzeugt
    2. und an func_a() weitergegeben.
    3. Darin wird die benötigte Größe ermittelt, der Speicher reserviert und das Array befüllt.
    4. Danach geht er aus func_a() raus.
    5. Aus dem obersten Sichtbarkeitsbereich wird der nun befüllte Pointer an func_b() weitergegeben.
    6. Darin wird er benutzt und deleted.

    Wenn ich unmittelbar nach dem delete ein Programmabbruch erzwinge, erhalte ich Memory Leaks. Wenn ich weitermache erhalte ich einen nicht nachvollziehbaren Programmfluss.



  • asdasdasdasd schrieb:

    Der Programmfluss ist so:

    1. Pointer wird in außerhalb von func_a() erzeugt
    2. und an func_a() weitergegeben.
    3. Darin wird die benötigte Größe ermittelt, der Speicher reserviert und das Array befüllt.
    4. Danach geht er aus func_a() raus.
    5. Aus dem obersten Sichtbarkeitsbereich wird der nun befüllte Pointer an func_b() weitergegeben.
    6. Darin wird er benutzt und deleted.

    Wenn ich unmittelbar nach dem delete ein Programmabbruch erzwinge, erhalte ich Memory Leaks. Wenn ich weitermache erhalte ich einen nicht nachvollziehbaren Programmfluss.

    Da scheint wohl irgendwo der Wurm drin zu sein.
    Der Ablauf gibt nicht viel Raum für Memory Leaks, oder "nicht nachvollziehbaren Programmfluss.

    #include <cstddef>
    #include <cassert>
    
    void create(float*& p, std::size_t N){
      p = new float[N];
    }
    
    void destroy(float*& p, std::size_t){
      delete [] p;
      p=0;
    }
    
    int main(){
      float *p = 0;
      create(p, 50);
      assert(p!=0);
      destroy(p,50);
      assert(p==0);
    }
    

    Was sollte da passieren? Ausser bei:
    3) ...wird befüllt...
    und
    6) ...wird benutzt...



  • Furble Wurble schrieb:

    ...

    Hmm... dann muss ich den Fehler woanders suchen... danke schonmal an alle.



  • Redesign mit einem modernen C++ Stil!

    asdasdasdasd schrieb:

    Ich schaffe es nicht einen Memory Leak loszuwerden.

    Wenn Du C++ modern verwendet, ist die Leckgefahr verschwindend klein.

    asdasdasdasd schrieb:

    Normalerweise arbeite ich nicht mit manueller Speicherverwaltung, bin jetzt aber durch eine externe Vorgabe dazu gezwungen worden.

    Manuell Speicher verwalten ist ja auch doof. Dabei macht man nur Fehler. Gib diese Verantwortung möglichst früh an "schlaue Objekte" ab.

    Beispiel:

    void ungeschickt(char const* filename)
    {
      FILE* f = fopen(filename,"r");
      ...
      fclose(f);
    }
    
    void schlau(char const* filename)
    {
      std::ifstream f (filename);
      ...
    }
    

    Das schlaue daran ist, dass das ifstream-Objekt sich um die Resource kümmern, nicht du selbst. Es gilt also nicht nur um Speicher, sondern für alle möglichen Arten von Resourcen.

    Wo kommt denn der Zeiger jetzt eigentlich her? Kannst du das nicht durch einen std::vector ersetzen? Sonst guck mal, ob boost::scoped_array vielleicht etwas für dich ist. Beides sind Beispiele für Klassen, die sich verantwortlich für reservierten Speicher fühlen und ihn automatisch wegräumen, wenn die entsprechenden Instanzen zerstört werden.


Anmelden zum Antworten