Ungewollter aufruf von Struct Destructor bei Kopieren in Vector



  • Hallo
    mir ist nicht klar warum der Struct Destructor bei push_back aufgerufen wird.
    Was mache ich falsch ?

    [cpp]

    struct sTest_t
    {
     sTest_t()
     {
       pfDat = static_cast<float*>( malloc(100*sizeof(float)) );
     }
     ~sTest_t()
     {
      free(pfDat)
     }
     float *pfDat;
    };
    
    void main(void)
    {
     std::vector<sTest_t> vTest;
    
     for( int iPtr =0; iPtr < 3; iPtr++
      vTest.push_back(*(new sTest_t));
    
    }
    


  • Objekte werden in den vector kopiert, d.h. du möchtest entweder:

    vec.push_back(sTest_t()); // Objekt am Stack anlegen und in den vec kopieren, nach der Kopie (Copy-Constructor fehlt bei dir! Bitte Rule of three beachten!) wird hier auch der Destructor des außen liegenden Objekts aufgerufen
    

    Oder du speicherst dir den Zeiger:

    vector<sTest_t*> ptrvec;
    ptrvec.push_back(new sTest_t());
    
    ...
    
    for(...)
        delete ptrvec[i]; // zu jedem new gibts ein delete (fehlt bei dir oben auch)
    

    MfG SideWinder



  • Ich erzeuge die Struct doch bereits mit dem Operator new
    und damit liegt sie doch im Heap weswegen bei dem push_back der Destructor
    nicht ausgeführt werden dürfte weil das Objekt doch im Heap weiterlebt.
    Komischerweise wir der Destructor auch nur beim Letzten Schleifendurchgang aufgerufen.

    Was ich nicht machen möchte ist das Speichern von Zeigern auf die Struct.
    Wie müsste so ein Copy Constructor des Vectors aussehen?



  • Mal etwas überarbeitet:

    struct sTest_t
    {
        sTest_t() : data(100)
        { }
        std::vector<float> data; //wozu das gehampel mit malloc?
    };
    
    int main( ) //void main(...) ist nicht standardkonform
    {
        std::vector<sTest_t> vTest;
    
        for( int i = 0; i < 3; ++i)
        {
            vTest.push_back((sTest_t())); //nichts mehr mit new. speicher wird automatisch freigegeben
        }    
    }
    


  • Maximizer schrieb:

    Hallo
    mir ist nicht klar warum der Struct Destructor bei push_back aufgerufen wird.
    Was mache ich falsch ?

    [cpp]

    struct sTest_t
    {
     sTest_t()
     {
       pfDat = static_cast<float*>( malloc(100*sizeof(float)) );
     }
     ~sTest_t()
     {
      free(pfDat)
     }
     float *pfDat;
    };
    
    void main(void)
    {
     std::vector<sTest_t> vTest;
    
     for( int iPtr =0; iPtr < 3; iPtr++
      vTest.push_back(*(new sTest_t)); << Bäm!
    
    }
    

    Du dereferenzierst den Zeiger bei der Übergabe an die push_back Methode, damit verlierst du die Information, dass es sich um einen Zeiger handelt. Du machst gerade so ziemlich alles falsch, was man falsch machen kann.

    1. Du erzeugst ein Speicherleck, weil du nicht die Zeiger im Vektor ablegst und hinterher wieder löschst, sondern du erzeugst ein anonymes Objekt auf dem Heap, dessen Kopie im Vektor abgelegt wird.
    2. Da der korrekte Zuweisungsoperator fehlt erzeugst du in den Objekten im Vektor dangling Pointers, denn durch den fehlenden Zuweisungsoperator wird der pfDat Zeiger einfach kopiert. Wenn der Vektor reallokieren muss erzeugt er temporäre Kopien von Objekten, die bei ihrer Zerstörung pfDat wieder freigeben. Da aber der nur rohe Zeiger kopiert wurde zeigt der pfDat Zeiger der erstellten Kopien in´s Nirvana.


    1. Copy-Konstruktor fehlt ebenso

Log in to reply