Speicher-Leak bei push_back
-
Dann wäre mehr als ein Block verloren.
-
ne exit benutze ich nicht. das eigenartige ist ja, dass es nur zu dem fehler kommnt, wenn ich einen zweiten eintrag im vektor hinzufüge also. wenn das if mit high_hit== count_hit aufgerufen wird. beim anderen if gibt es eben keine probleme

undmit erzeuge ich auch nix innerhalb des vektors.
EDIT: im späteren verlauf des Programmes mache ich dies kommt ja einem exit gleich oder? aber darf dies zu jenem problem führen?
for(counter = 0; counter < max_startpositions.size(); counter++) { if((return_value == HIT) && (max_startpositions[counter] == startposition)) { old_endposition = endposition; if(global_hit > 1) { multiple_hits = true; global_hit--; return HIT_MORE; } multiple_hits = false; return HIT; }naja ich habe jetzt max_startpositions.clear();
vor den returns eingefügt das problem ist noch immer da:/ obwohl jetzt ja eigentlich nix mehr im vektor stehen dürfte...
-
std::vector::clear gibt nicht zwingend den Speicher frei, bzw wird es bei den allermeisten Implementierungen nicht tun. Löschen kannst du ihn explizit so:
std::vector<int> bla = { 1, 2, 3 }; { std::vector<int> foo; std::swap(foo, bla); }
-
Das geht schon wieder in Richtung Schnitzeljagd.

Irgendwo hantierst Du mit
newunddeleteund Dir geht Speicher flöten, guck da!Oder vielleicht hast Du irgendwo einen Destruktor, der nicht virtuell ist, in einer Basisklasse...
Ein
vector<int>wird kaum ein Speicherleck haben...
-
Ethon schrieb:
std::vector::clear gibt nicht zwingend den Speicher frei, bzw wird es bei den allermeisten Implementierungen nicht tun. Löschen kannst du ihn explizit so:
std::vector<int> bla = { 1, 2, 3 }; { std::vector<int> foo; std::swap(foo, bla); }genau das wars!
danke!!!

-
Oder kuerzer:
std::vector<int>().swap(bla);
-
nero08 schrieb:
Ethon schrieb:
std::vector::clear gibt nicht zwingend den Speicher frei, bzw wird es bei den allermeisten Implementierungen nicht tun. Löschen kannst du ihn explizit so:
std::vector<int> bla = { 1, 2, 3 }; { std::vector<int> foo; std::swap(foo, bla); }genau das wars!
danke!!!

Ich verstehe nicht, was das eine mit dem anderen zu tun hat.
Dasvectorallozierten Speicher nicht wieder freigibt: geschenkt. Denn spätestens bei Programmende wird er das tun, es sei denn, man schafft es irgendwie seinen D'tor zu überspringen, z.B. mit dem beschriebenenexit().Ich kann gerade keine Versuche mit valgrind und
vectoranstellen, aber ich behaupte, dassClear-and-minimize/shrink_to_fit()die Symptome und nicht die Ursachen beseitigt.Eingebungen, Erläuterungen, Erklärungen für mich?
-
Auch wenn ich hier ein Selbstgespräch führe:
Was Du mit demswap()machst, löst ein ganz anderes Problem!Dein Programm ruft den D'tor von
startpositionsnicht auf, da liegt der Hund begraben.Ist die Klasse
Manvielleicht von irgendwas abgeleitet?startpositionist Member vonMan, richtig?Ich denke Du solltest dem noch auf den Grund gehen, wenn Du C++ lernst.
Hier mal ein Beispiel, was ich mir vorstellen könnte, was passiert. Es ist so geschrieben, dass der Trace Deinem sehr ähnlich ist.
Du kannst das Speicherleck beseitigen in dem Du eine der beiden markierten Zeilen A oder B hinzufügst.
Aber während B die Symptome kaschiert, beseitigt A den Fehler!#include <vector> struct Foo { virtual void clear_and_minimize() = 0; // virtual ~Foo() {} // Zeile A }; struct Bar : Foo{ std::vector<int> v; Bar() { v.push_back(42); v.push_back(42); } void clear_and_minimize() { std::vector<int>().swap(v); } }; int main(){ Foo* f = new Bar; // f->clear_and_minimize(); // Zeile B delete f; }valgrind schrieb:
==3483== HEAP SUMMARY:
==3483== in use at exit: 8 bytes in 1 blocks
==3483== total heap usage: 3 allocs, 2 frees, 44 bytes allocated
==3483==
==3483== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3483== at 0x4C2A3D7: operator new(unsigned long) (vg_replace_malloc.c:287)
==3483== by 0x4015F3: __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) (in /tmp/test)
==3483== by 0x401406: std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) (in /tmp/test)
==3483== by 0x400F50: std::vector<int, std::allocator<int> >::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&) (in /tmp/test)
==3483== by 0x400CA1: std::vector<int, std::allocator<int> >::push_back(int const&) (in /tmp/test)
==3483== by 0x400B25: Bar::Bar() (in /tmp/test)
==3483== by 0x400A56: main (in /tmp/test)
==3483==
==3483== LEAK SUMMARY:
==3483== definitely lost: 8 bytes in 1 blocksIch hoffe Du schaust nochmal drauf.
Allein schon, weil Du wahrscheinlich überall im code unnötige aufrufe vonswap()hast...
-
sorry für die späte Antowrt hatte in den letzten Tagen viel zu tun

ich versuche gerade zu verstehen, was du meisnt... liege ich richtig, dass du die Vermutung hast, dass ich den destruktor vergessen habe?
okay die klasse also man ist abgleleitet... der destruktor wird erzeugt, aber ist im moment leer. gehe ich richtig in der Vermutung, dass du meisnt ich soll swap() im Destruktor aufrufen?
aber ganz klar ist mir die situation immer noch nicht in der regel wird doch ein vector automatisch freigegeben?
danke jedenfalls für die nette Unterstützung

-
Das wichtigste wäre erst einmal, den wahren Fehler zu finden. Das was du als Lösung beschrieben hast, kann nicht funktioniert haben. Zumindest nicht, wenn es in deinem Programm mit rechten Dingen zugeht (aber dann wäre der Fehler gar nicht erst aufgetreten). Daher mein Tipp: Du erzeugst irgendwo furchtbar undefiniertes Verhalten und es passiert einfach Unsinn
. Als du dann an anderer Stelle etwas geändert hast, passierte anderer Unsinn oder zwei Sorten Unsinn haben sich gegenseitig aufgehoben. Auf jeden Fall ist es nicht richtig, denn ein vector kann gar keinen Speicher lecken, so lange seine internen Strukturen intakt bleiben, wenn du damit ein Problem hattest, dann hast du es nun bloß vertuscht. Irgendetwas muss dir deinen vector an sich zerschießen.
-
Du musst den Destruktor in der Basisklasse virtuell machen, damit der richtige ausgeführt wird, wenn du ein Objekt einer Kindklasse durch einen Basisklassenzeiger löschst. Generell sollten polymorphe Basisklassen einen virtuellen Destruktor haben, um genau diese Problematik zu vermeiden.
-
Ethon schrieb:
std::vector::clear gibt nicht zwingend den Speicher frei, bzw wird es bei den allermeisten Implementierungen nicht tun.
Wenn es darum geht, den Speicher wieder frei zu geben, schlage ich vor, das mit Gültigkeitsbereichen zu regeln.
-
nero08 schrieb:
liege ich richtig, dass du die Vermutung hast, dass ich den destruktor vergessen habe?
Den Destruktor der Basisklasse, ja. Vergessen, oder nicht virtuell deklariert, siehe seldons Antwort.
nero08 schrieb:
gehe ich richtig in der Vermutung, dass du meisnt ich soll swap() im Destruktor aufrufen?
Nein. Die swaps schmeisst Du alle wieder raus. Es sei denn Dir geht der Speicher aus.
nero08 schrieb:
aber ganz klar ist mir die situation immer noch nicht in der regel wird doch ein vector automatisch freigegeben?
Das stimmt, deswegen ist der vector ja so bequem. Wenn das Objekt, dessen Member der vector ist zerstört wird, gibt der vector den allozierten Speicher frei und gut is'.
Wird allerdings wie im Beispiel der D'tor von - in diesem Fall -Barnicht aufgerufen, weil~Foo()nicht virtuell ist, wird auch der D'tor des vector nicht aufgerufen. Damit bleibt der Inhalt des vectors im Speicher erhalten und ist unerreichbar verloren.
Mit demswap()sorgst Du nun dafür, dass der vector dessen D'tor nicht aufgerufen wird, 0 Bytes alloziert, d.h. valgrind bekommt davon nix mit.Allerdings ist das Fehlen eines virtuellem D'tor in einem Fall wie oben zusätzlich noch UB (s. C++ 5.3.5), müsste also auf jeden Fall gefixt werden.
Und obacht: dass das der Fehler ist, ist reine Spekulation!
Aberswap()fixt keinen Fehler - siehe auch die Antwort von SeppJ.Good Hunting!

-
ja da muss ich wohl nochmal DANKE sagen!
ich hatte wirklich in meiner Basisklasse keinen destruktor

habe ihn jetzt hinzugefügt und die swaps gekickt - und keine leaks

allerding stellt sich mir hier ein kleines verständnisproblem vl. mag wer daraug eingehen

Also ich habe in meiner Unterklasse einen vector welcher alle gelöschten steine speichert. diesen brauche ich bei einem erneuten aufruf der klasse wieder für eine überprüfung also ob man einen zug machen darf.
wird nicht durch den aufruf des destruktors dieser vektor also auch der Inhalt gelöscht?
EDIT: den vektor muss ich schon noch passend entleeren, aber wenn ich mich noch an die vorherigen Beiträge erinnere muss ich dies mit swap mache oder reicht clear doch aus?
also im Prinzip wird dann mittel destruktor der vektor im unterschied zu zuvor wirklich auch gelöscht?