std::string gibt Speicher nicht frei?
-
Schon mal die Implementation von std::string angeschaut? Oder mit dem Debugger durchgesteppt?
Und wie schauen die Signaturen deiner überladenen Operatoren aus?
-
string::clear() löscht zwar den Inhalt der Stringvariablen, verringert/löscht aber nicht den dafür verwendeten Speicher.
Das geht z.Bsp. sostring test("Irgend ein String"); //Speicher freigeben string().swap(test);Bist du sicher, dass deine string-Implementation überhaupt new/delete verwendet?
-
Ich habe hier gerade noch ein paar sehr Merkwürdige Fehler entdeckt. Ich habe mir mal die Adressen der nicht freigegebenen Pointer ausgeben lassen und mal geschaut, wo die herkommen. Bei manchen ist ganz klar per Debugger nachvollziehbar, dass sie mittels delete wieder freigegeben werden.
Ein Beispiel: Ich habe einen vector aus MathNode* Pointer. Also so: std::vector<MathNode*>. Irgendwann werden alle Objekte gelöscht, auf die eine Referenz im Vektor gehalten wurde:/*bgein() und end() gehören zu der Klasse, in der die Schleife verwendet wird und geben begin() und end() des Vectors zurück...*/ for(std::vector<MathNode*>::iterator it = begin(); it != end(); ++it) delete (*it);
-
Nach ein Bisschen Forschung ist mir nun aufgefallen, dass std::vector anscheinend Speicher belegt, sobald man ein Objekt mittels push_back() einfügt. Allerdings wird dieser Speicher wie auf wundersame Weise nicht freigegeben...
-
schau mal hier: http://www.henkessoft.de/C++/C++ Fortgeschrittene/C++_Fortgeschrittene.htm#2.3._Unsere_Testklasse_im_Container
Vielleicht bringt dich das weiter.
-
hmmm... nicht so wirklich.
Ich habe nochmal ein Bisschen mit dem Debugger geschaut, wo genau der Speicher reserviert wird. Mehrere STL-Komponenten reservieren anscheinend Speicher im Voraus. Hier mal ein Stack-Trace bis zur Reservierung des Speichers, der nicht freigegeben wird.Ein vector, der beim ersten push_back() Speicher reserviert:
13 operator new() at ../tests/NewDeleteOperator.cpp:74 0x0804e4be 12 std::__default_alloc_template<true, 0>::_S_chunk_alloc() 0xb7f65a6b 11 std::__default_alloc_template<true, 0>::_S_refill() 0xb7f6597d 10 std::__default_alloc_template<true, 0>::allocate() 0xb7f65678 9 std::__simple_alloc<MathNode*, std::__default_alloc_template<true, 0> >::allocate() at stl_alloc.h:232 0x08056b8d 8 std::_Vector_alloc_base<MathNode*, std::allocator<MathNode*>, true>::_M_allocate() at stl_vector.h:127 0x08056b69 7 std::vector<MathNode*, std::allocator<MathNode*> >::_M_insert_aux() at vector.tcc:236 0x080566dc 6 std::vector<MathNode*, std::allocator<MathNode*> >::push_back() at stl_vector.h:603 0x080561c8Eine Map, die Speicher reserviert:
14 operator new() at ../tests/NewDeleteOperator.cpp:74 0x0804e4be 13 std::__default_alloc_template<true, 0>::_S_chunk_alloc() 0xb7f29a6b 12 std::__default_alloc_template<true, 0>::_S_refill() 0xb7f2997d 11 std::__default_alloc_template<true, 0>::allocate() 0xb7f29678 10 std::__simple_alloc<std::_Rb_tree_node<std::pair<std::string const, Number*> >, std::__default_alloc_template<true, 0> >::allocate() at stl_alloc.h:232 0x080576a5 9 std::_Rb_tree_alloc_base<std::pair<std::string const, Number*>, std::allocator<std::pair<std::string const, Number*> >, true>::_M_get_node() at stl_tree.h:564 0x08057678 8 _Rb_tree_base() at stl_tree.h:579 0x0805764f 7 _Rb_tree() at stl_tree.h:730 0x08057610 6 map() at stl_map.h:144 0x080575b9 . . .
-
Wie verhält sich deine Testroutine in Bezug auf statische Objekte, die mit new angelegt worden sind?
Verwendet man z.B. Autopointer zum Löschen dieser Objekte weiss man nicht unbedingt zu welchen Zeitpunkt diese gelöscht werden.
-
Habe ich noch nicht ausprobiert, weil ich derzeit keine autopointer verwende. Was mir wirklich nützen würde wäre eine Funktion, mit der ich der STL sagen kann, dass Sie allen reservierten Speicher freigeben soll..
-
Wenn du feststellen möchtest ob alles korrekt freigegeben worden ist, kannst du dies mit oder ohne STL erst dann sagen, wenn das zu testende Programm beendet wurde.
(Es sei denn du verzichtest gänzlich auf statische Strukturen und Bibliotheken, die solche intern nutzen.)Das automatische Erkennen von Speicherleaks ist nunmal nicht so ganz einfach, ansonsten würde wohl keiner die sehr günstigen *hust* Analysewerkzeuge zum Finden von Speicherleaks kaufen.

-
Mathias schrieb:
Das automatische Erkennen von Speicherleaks ist nunmal nicht so ganz einfach
Naja, eigentlich schon. Du musst es halt blos in die Anwendung implementieren, und nicht hinterher versuchen, das irgendwie auf die Reihe zu bekommen. Ist bei mir gerade mal eine Headerdatei mit überladenen Operatoren new/delete und 'ner Trace Klasse.
Ohne hackbert nahetreten zu wollen, ich glaube nicht, dass seine STL Implementation Speicherlecks verursacht. Obwohl ich darauf nicht wetten würde, immerhin werkelt er unter Linux.
Ich glaube er hat irgendwo 'nen Denkfehler. Oder irgendeine krumme Geschichte ist bei seinen Tests mit im Spiel. Wann wird denn deine Zählvariable ausgegeben? Ein Problem bei mir war zB, dass ich meine Ergebnisse ausgegeben hatte, obwohl noch nicht alle Speicherfreigaben erfolgt waren. Grund dafür waren Objekte mit statischer Lebensdauer, deren ctor erst nach dem ctor meiner Trace Klasse aufgerufen worden. Evtl. ist es ein ähnliches Problem bei hackbert.