memory leaks bei std::vector



  • Hallo Zusammen!

    Ich habe folgendes Problem.
    Ich habe eine Klasse, welche als Membervariable einen vector besitzen soll.
    Nun möchte ich diesen vector mit push_back mit werten füllen.
    Das Programm kompiliert ohne Probleme und es tauchen auch keine sichtbaren Fehler auf. Nur wenn ich das Programm schließe, ergeben sich memory leaks.
    Woran kann das liegen??

    Kurz ein wenig Code:

    class Test{
    
    private:
    std::vector<int> v;
    void foo();
    }
    void Test::foo(){
    .....
    v.push_back(i);
    .....
    }
    

    Danke schonmal
    Grüße
    Froni



  • womit hast du die leaks entdeckt ?
    versuch doch mal einen vektor zur laufzeit zu erstellen also

    void Test::foo(){
    std::vector<int> v;
    .....
    v.push_back(i);
    .....
    }
    

    und wenn nach der ausführung der methode keine leaks auftreten, wird dein problem wahrscheinlich woander liegen.



  • fronika schrieb:

    Nur wenn ich das Programm schließe, ergeben sich memory leaks.
    Woran kann das liegen??

    An deinem Code. In dem gezeigten Teil steckt jedenfalls kein Leak. Es kommt wohl darauf an, was du mit der Klasse machst. Wenn du ein Test-Objekt mit new anlegst, aber nicht wieder freigibst, hast du natürlich ein Speicherleck. Das hat aber mit dem Vector nichts zu tun.



  • woher weißt du von den Leaks? Vor allem beim Beenden? Da wird doch eh alles wieder freigegeben, zu beachten ist auch die interne Struktur eines Vektors der sowieso etwas... naja speicherlastiger ist da er echtzeitzugriffe auf seine elemente erlaubt.

    Im grunde ist das ja nicht mehr als ein dynamisches array was zur Laufzeit vergrößert ( verdoppelt wird )

    als beispiel...

    initialisiert wird dein Vektor mit 20 Elementen. Willst du nun das 21 element einfügen wird neuer speicher für 2*20 Elemente reserviert. willst du nun das 41 Element speichern wird platz für 2*40 elemente angefordert und so weiter. Daher ist es schon sinnvoll den vektor so vor zu initialisieren das er möglichst gut gefüllt ist und nicht so sehr über seine grenzen gleich erweitert werden muss.

    Also es ist blödsinn ihn mit 1 vor zu initialisieren wenn eh auf jedenfall 1000 Werte gespeichert werden. und auch blödsinn ihn mit 1000 Vor zu initialisieren wen nur 10 elemente gehalten werden.

    Und wen es dir wirklich auf speicheroptimierung anstatt auf Geschwindigkeit bzw echtzeitzugriff ankommt nimm statt std::vektor eine std::list dort hast du auf jedenfall nur so viel platz verbraucht wie auch elemente sind + die Zeiger aufs jeweils folgede element.

    Dafür entfällt halt der echtzeitzugriff. Daher auch eine art Goldene Regel der Informatik. Was man an Platz einspart büßt man auch an geschwindigkeit ein.

    Im grunde halten sich speicherplatz und laufzeitverhalten irgendwo die Waage. Gibt es einen Algorythmus der etwas sehr schnell erledigt ist er meist speicherintensiv und umgekehrt. Ggf hilft dir die kurze beschreibung bei deinen speicherleaks weiter.



  • @Fedaykin: Sehr ausführlich, aber leider falsch. Daß der Vektor seine grösse bei Bedarf verdoppelt ist ein möglicher algorithmus, aber vom Standard nicht vorgeschrieben. Genauso kann auch eine Liste Elemente vorallokieren und über in-place-Konstruktor-Aufrufe erst später benutzen.

    Echtzeitzugriff ist auch ein Begriff, der hier sinnfrei ist. Du meinst sicherlich, daß der Zugriff auf ein beliebiges Element in einem Vektor eine konstante Zeit beansprucht. Dagegen muß ich durch eine Liste iterieren, wenn ich ein bestimmtes Element suche, was lineares Zugriffsverhalten bedeutet. Es kommt halt auf die Anwendung an, ob ich random-access-Zugriffe benötige.

    Für die Speicheroptimierung sollte man bei einem Vektor die Methode reserve(size_type) verwenden, wenn die Anzahl der Elemente im voraus bekannt ist. Aber selbst das garantiert nicht, daß nur genau diese Anzahl reserviert wird.

    Tntnet



  • Naja nicht sooo falsch aber falscher als es einfach sein sollte.

    Ja der zugriff auf Vectorelemente ist ein O(1) was für mich sowas wie gleichbedeutend mit echtzeitzugriff ist , wobei eine Liste O(n) zugriffe erfordert da ich ja im ungünstigsten fall auch immer durch die liste itererieren muss.

    Was und wie genau vorreserviert wird ist wirklich nicht im Standard beschrieben, ich glaube sogar man kann da selber angaben machen wenn man den Vector anlegt??? In Java ging das im constructor. Also eine init size und eine growth rate sozusagen. Aber soweit ich informiert bin wird ohne irgendwas der platz halt immer verdoppelt und um die grundlegende Funktion eines Vektors zu Erläutern reichts doch oder? Ich bin ja ganz früher auch dem Irrglauben aufgelegen das ein Vektor nur soviel speicher benötigt wie elemente enthalten sind.



  • Ok - so richtig falsch war es nicht - nur so ein bisschen 😃 .

    Eine Liste benötigt nicht O(n) Zugriffe. Das gilt nur, wenn ich wirklich auf das n-te Element zugreifen möchte. Wenn ich das tun möchte, was häufig gar nicht notwendig ist, dann ist die Liste wahrscheinlich nicht die richtige Wahl.

    Und die Sache mit dem Vektor ist immer noch nicht so ganz richtig. Es ist nicht die grundlegende Funktion eines Vektors, die Du da erläuterst, sondern nur eine mögliche Implementierung (wenn auch eine durchaus sinnvolle). Bei C++ muß man zwischen Definition (im Standard) und Implementierung unterscheiden. Die Verdoppelung ist nicht definiert, aber auch nicht falsch. Der Standard lässt da gewisse Freiheitsgrade. Mag sein, daß Du bei einer bestimmten Implementierung ein solches Verhalten beobachtest hast, was aber nicht heißt, daß das mit der nächsten Version deines Compilers oder mit einem anderen Compiler (bzw. Bibliothek) auch so ist.

    Eine growth-rate gibt es im std::vector nicht. Dein Glaube, daß man dem std::vector irgendwelche Angaben machen kann, wie er zu wachsen hat, ist falsch (und nicht nur ein bisschen :p ).

    Wenn es um solche Fragen geht, dann solltes Du in eine C++-Referenz schauen, bevor Du irgendwelche Aussagen machst, die möglicherweise richtig sind. Ich verwende gerne die STL-Referenz von SGI. Da ist recht genau spezifiziert, was std::vector machen soll. Allerdings muß man da aufpassen, da einige SGI-Erweiterungen erklärt sind.

    Tntnet



  • ich hab das mit der Growth rate auch nicht gesagt das es bei C++ so ist, ich weiss nur das ich bei java sowas gesehen habe und vermute das sowas ggf auch bei C++ geben könnte. Ich fände es nämlich gar nicht so dämlich wenn ich weiß wie stark mein Vector wächst.


Anmelden zum Antworten