speicher wieder freigeben



  • Tagchen,

    hab ne kleine Frage..
    und zwar: wenn ich eine Methode habe die als rückkabe wert ein mit new erzeugtes Array hat und irgendwann wird diese methode aufgerufen, wo muss ich dann diesen speicher letztendlich wieder freigeben am ende des programms?
    hab mir gedacht das passiert im destruktor aber da kann ich ja nicht auf lokale sachen dieser methode zugreifen...?



  • Den Speicher musst du einfach wieder freigeben, wenn du ihn nicht mehr brauchst.


  • Administrator

    Sobald du den Speicher nicht mehr brauchst, gibst du ihn per Zeiger und delete[] wieder frei. Wo liegt das Problem?

    Edit: Auf die Sekunde gleichzeitig ^^
    Aber ich kann mich nur nochmals wiederholen, dort wo du ihn nicht mehr brauchst. Also wahrscheinlich nach der for-Schleife.
    Allerdings ist das eher schlechter Stil. Wenn man Speicherownership weitergibt, sollte man das eher über Smartpointer machen. Oder am besten es gar nicht erst soweit kommen lassen.

    Grüssli



  • und wo?
    dort wo ich dieses array von der methode zurück bekomm?

    using namespace std; 
    
    int* function() 
    { 
        int *b = new int[10]; 
        for(int i=0;i<10;i++) 
        { 
            b[i]=a*i; 
        } 
        return b; 
    } 
    
    int main() 
    { 
        int* x=NULL; 
        x=function(); 
    
        for(int i=0;i<10;i++) 
        { 
            cout<<x[i]<<endl; 
        } 
    
        return 0; 
    }
    

    in diesem beispiel wäre der speicher noch reserviert oder? wo muss ich freigeben?



  • Es ist sowieso immer blöd, wenn eine Funktion Speicher reserviert, ihn aber nicht selbst freigibt. Schreib am besten eine zweite Funktion "functionDelete" oder so, die das delete ausführt. Die Namensgebung sollte so sein, dass unmissverständlich klar wird, dass die eine Funktion Speicher anfordert und die andere ihn wieder freigibt. Also um Beispiel MyArrayNew und MyArrayDelete oder sowas...

    Direkte Antwort auf deine Frage: klar, der Speicher muss im Beispiel dort freigegeben werden, wo du das Array von der Funktion zurückbekommst, also in der main. Ist auch logisch, die Funktion selbst kann es schlecht machen. Der Sinn ist ja schließlich, dass das Array über die Lebensdauer der Funktion hinaus existiert...



  • _matze schrieb:

    Schreib am besten eine zweite Funktion "functionDelete" oder so, die das delete ausführt.

    wie weiß denn die andre funktion welches array gemeint ist bzw wie greif ich da drauf zu ? da bekomm ich ja dann wieder not declared in this scope ect....


  • Administrator

    cryps schrieb:

    wie weiß denn die andre funktion welches array gemeint ist bzw wie greif ich da drauf zu ? da bekomm ich ja dann wieder not declared in this scope ect....

    delete[] oder delete erwartet die Adresse auf den entsprechenden Speicherbereich. Du musst also einfach die Adresse übergeben, genau wie du es auch über den Rückgabewert machst.

    Grüssli



  • d.h.:
    so passt das dann bei diesem codestück:

    for (iter; iter < rectangles.size(); iter++) { 
    
    cb->fillrect(rectangles[iter]->getCoordinates()[0], rectangles[iter]->getCoordinates()[1]);	
    delete[] rectangles[iter]->getCoordinates();
    
    	}
    

    getCoordinates() is die oben besprochene methode mit der array rückgabe...



  • Nein, das ist Blödsinn. Du rufst getCoordinates hier dreimal auf. Bei den ersten Aufrufen gibst du den Speicher nicht frei, beim letzten gibst du ihn frei, tust aber sonst nichts damit.

    Ruf die Funktion nur einmal auf, merk dir den Rückgabewert in einem Zeiger, und gib den frei, wenn du ihn nicht mehr brauchst.



  • ja klar hast natürlich recht.. voller blödsinn.. naja dann hab ichs also so

    for (iter; iter < rectangles.size(); iter++) 
    { 
    
    int* coordinates = rectangles[iter]->getCoordinates();
    cb->fillrect(coordinates[0], coordinates[1]);
    
    delete[] coordinates;
    
    }
    

    ist dann der ganze speicher frei? nicht oder? ich muss noch den speicher von diesem Methodenaufruf in zeile 4 freigeben.... ?



  • Ist es überhaupt erforderlich, dass die Funktion einen Zeiger zurück gibt. Bei zwei Integern täte eine Kopie auch nicht weh.

    return std::make_pair(x, y);
    

    oder die Koordinaten in eine Struktur packen und per Kopie zurückgeben:

    struct Coordinate
    {
        int x;
        int y;
    
        Coordinate(int x=0, int y=0)
            : x(x), y(y)
            { }
    };
    
    // ...
        return Coordinate(x, y);
    
    // ...
        Coordinate coord = getCoordinateWhatEver();
        int foo = coord.x;
        int bar = coord.y;
    

    So muss man sich auch keine Gedanken um die Speicheranforderung (die in diesem Falle ja nicht stattfinden muss) und dessen Freigabe machen.

    ---

    In deinem Fall iterierst du (wahrscheinlich) über einen std::vector oder std::list mit Zeigern auf konkrete Rectangle-Objekte. Wie bereits bei den Vorrednern gefragt: Warum Zeiger?

    Vereinfacht ungetestet:

    struct Rectangle
    {
        Coordinate coordinate;
        // ...
    };
    
    // ...
    
    std::vector<Rectangle> rects;
    // vector füllen
    
    for(std::vector<Rectangle>::const_iterator iter=rects.begin();
            iter != rects.end();
            ++iter) {
        doSomeThingWith(iter->coordinate);
    }
    

    Sind natürlich alles nur Mutmaßungen, da ich dein Datenmodell nicht kenne.

    Grüße... Heiko


Anmelden zum Antworten