Speicherfreigabe std::map



  • hallo,

    warum und wie wird der Speicher einer Map automatisch wieder freigegeben?

    #include <map>
    
    using namespace std;
    
    int main () {
    
        map <int, int> mymap;
    
        for(int i = 0; i < 1000000; i++)
        {
            mymap[i] = i+1235;
        }
    
        //mymap.clear();
    return 1;
    
    }
    

    wenn ich das programm mit und ohne clear bauen und anschließend mit valgrind --tool=memcheck ausführe wird der Sepicher scheinbar immer freigegeben, warum?



  • Weil map so gebaut ist. Stichwort: RAII



  • Also auf das "warum" kann ich antworten 😃

    Man will den Programmierern Verantwortung abnehmen. Sie sollen sich nicht mehr selbst um Speicherbereinigungen kümmern müssen. Denn muss sich ein Programmierer selbst darum kümmern, sind das immer potentielle Fehlerquellen 🙂

    Das ist übrigens bei allen modernen C++-Containerklassen so.

    Vom "wie" hab ich keine Ahnung, hab selbst erst angefangen mit C++.



  • ok, danke 🙂



  • nippler92 schrieb:

    [...] wird der Sepicher scheinbar immer freigegeben, warum?

    Weil sich das so gehört für einen C++ Container. Quasi bei der schließenden Klammer der main -Funktion, wo die "lokalen Variablen weggeräumt werden", wird automatisch der Destruktor von mymap aufgerufen. Und der wurde so definiert, dass der Speicher, den mymap besitzt, automatisch freigegeben wird. Aber nicht nur beim Zerstören passiert etwas Besonderes. Auch bei dem Versuch, das Objekt zu kopieren oder zuzuweisen wird vom Klassenautor definierter Code ausgeführt, der hier "das Richtige" macht. Du erhältst damit einen Typen, den Du so wie int und double bzgl Kopieren, Zuweisen und Zerstören verwenden kannst -- die Map speichert nur eben nicht einen einzigen Wert, sondern mehrere. Aber diese mehreren Werte zusammengenommen stellen quasi einen neuen Wert des Map-Typs dar. Deswegen nennt man das manchmal auch "Werttyp". Werttypen machen einem das Leben als Programmierer leichter, weil man sich nicht mehr selbst um alles Kümmern muss. Dir kann es doch egal sein, wie die Map intern funktioniert. Hauptsache, du kannst ein Map-Objekt dazu benutzen, um einen "Map-Wert" zu speichern.



  • Ist in C++ der Zeitpunkt exakt vorgegeben, wann der Destruktor aufgerufen wird?

    In PHP ist das nämlich so, dass man den genauen Zeitpunkt nicht kennt, wann der Garbage Collector einen Destruktor aufruft, nachdem ein Objekt seinen Gültigkeitsbereich verlassen hat. Das entscheidet PHP mehr oder weniger nach Gutdünken selbst.



  • Ja, der Zeitpunkt ist genau definiert. Das Objekt wird zerstört, wenn es seinen Scope verlässt. Details gibt´s hier zu lesen



  • tröröö schrieb:

    Ist in C++ der Zeitpunkt exakt vorgegeben, wann der Destruktor aufgerufen wird?

    Ja, das ist in C++ deterministisch. Denk es dir so, als würde der Compiler automatisch aus

    int main() {
        string text = "hello world";
        cout << text << endl;
    }
    

    ein

    int main() {
        string text = "hello world";
        cout << text << endl;
        test.~string(); // <-- wird quasi vom Compiler automatisch eingefügt
                        //     NICHT "PER HAND" AUFRUFEN!
    }
    

    machen.

    Und das klappt dann auch bei komplizierteren Funktionen, die mehrere return s haben und ggf durch Ausnahmen irgendwann vorzeitig beendet werden. Spätestens das will man dann nämlich nicht mehr per Hand schreiben. Diese Aufräumarbeiten kann man dank Destruktoren dem Compiler überlassen, der dann die Destruktoraufrufe automatisch einfügt.

    Es gibt übrigens eine neue C++ FAQ bei isocpp.org:
    http://isocpp.org/wiki/faq/dtors

    (Dieses FAQ ist eine Kombination aus mehreren, u.a. von Stroustrup und Cline).


Log in to reply