Speichernutzungsverhalten von STL-Vector und Konsorten
-
Ja, Vectoren sind im Prinzip Wrapper für normale Arrays mit dynmaischer Speicherdauer.
Ein typischer Fehler, den man machen kann, ist das Arbeiten mit invalidierten Iteratoren oder invalidierten Zeigern auf Objekte in Containern.
-
Ich frage, weil ich teilweise potenziell recht lange std::lists und std::vectors by value returnen muss, und ich möchte ausschließen, dass die beim returnen angelegte Kopie mir den stack corrupted oder überlaufen lässt.
sizeof(std::vector) ist unabhaengig von seiner Laenge oder dessen Inhalt.
-
ich vermute dass der vector im speicher fragmentiert vorliegen kann, da ich zufällig abstürze bekommen habe, als ich nach einem resize mit memcpy zusammenhängende daten in den freien speicher laden wollte. man musste erst die std::copy etc funktionen benutzen, damit alles wieder funktionierte.
-
ich vermute dass der vector im speicher fragmentiert vorliegen kann,
Kann er nicht (seit dem Corrigendum von 2003).
Simon
-
Wird memcpy genutzt? Bleibst du immer innerhalb der Grenzen des Arrays/Vectoren?
Bedenke: Nur wenn du vector.at() nutzt prüft der Vector die Bounds, bei operator[] wird nicht geprüft!
Ansonsten jag doch mal valgrind auf dein Programm.
-
ich blieb innerhalb der vectorgrenzen. aber es kam bei sehr großen dateninhalten sporadisch zum programmabsturz ohne assert. bei kleinen datenmengen funktionierte memcpy. das hat mich auch nicht sonderlich verwundert, da ich generell von std::vector nicht viel halte. aber es ist doch verwunderlich zumindest funktioniert die klasse wenn man bei std::copy bleibt. aber ansonsten sollte man erwägen immer selbst ein array mit eigenen []-operatorenm zu implementieren.
-
dgrat schrieb:
das hat mich auch nicht sonderlich verwundert, da ich generell von std::vector nicht viel halte.
Wundert mich nicht, wenn jemand gegen die Implementierung statt gegen die Schnittstelle programmiert.
-
wenn du einen vector<string> oder vector<vector> hast und memcpy benutzt, wird die kiste auch irgendwann abstürzen.
-
Danke für die Antworten, hat mir einige hilfreiche Ansatzpunkte geboten. Habe jetzt mal konsequent copy constructors, Zuweisungs- und Vergleichsoperatoren für meine Klassen geschrieben. Mir sind dabei zwar einige mögliche issues aufgefallen, die ich jetzt abfangen kann, aber das wars scheinbar nicht (leider). Werde mal weiter rumsuchen.
Was valgrind angeht - ich bin leider auf ein Windowssystem beschränkt, muss da mal beim Chef etwas Lobbyarbeit betreiben. Nervt mich eh schon die ganze Zeit, dass die meisten guten Tools nicht laufen ^^
-
Für Windows gibts den Application Verifier.
BTW: Wenn Du schon Copy DTOR und Assignment Operator gemacht hast, dürfte ein DTOR auch angebracht sein.
Simon
-
Destruktoren schreibe ich immer, selbst wenn sie leer sind. Mit denen hatte ich schon zu viel Ärger.
-
theta schrieb:
Für Windows gibts den Application Verifier.
Sofern man MS Visual Studio verwendet.
-
Braunstein schrieb:
theta schrieb:
Für Windows gibts den Application Verifier.
Sofern man MS Visual Studio verwendet.
Die Alternative dazu wäre doch wohl MinGW, und für den gibts afaik auch valgrind.
-
The-Kenny schrieb:
Die Alternative dazu wäre doch wohl MinGW, und für den gibts afaik auch valgrind.
Aber nicht für Windows. Es gibt eine unter wine lauffähige Variante aber das wars auch schon.
-
Braunstein schrieb:
theta schrieb:
Für Windows gibts den Application Verifier.
Sofern man MS Visual Studio verwendet.
Muss nicht sein, kann auch separat gestartet werden.
Simon
-
Daniel der Gast schrieb:
...aber das wars scheinbar nicht (leider).
Das memcpy nicht unbedingt für Objekte geeignet ist, hast du aber auch verstanden? Und dabei ist es egal ob du auf C-Arrays oder std::vector setzt.
-
Memcpy verwende ich nicht. Alles was void* returned ist eh potenziell pfui ^^
Ich _glaube_ übrigens ich hab den bug exterminiert, kann aber nicht mit Sicherheit sagen, was genau es war. Habe ein größeres refactoring der Methode gemacht, die den Fehler scheinbar verursacht hat, jetzt läufts (wohl).
-
Übrigens bin ich nicht identisch mit dgrat (nur um Verwirrung vorzubeugen)
-
asc schrieb:
dgrat schrieb:
das hat mich auch nicht sonderlich verwundert, da ich generell von std::vector nicht viel halte.
Wundert mich nicht, wenn jemand gegen die Implementierung statt gegen die Schnittstelle programmiert.
zynismus ist die sprache schwacher geister.. vermutlich weiste selbser bicht, warum der fehler auftritt.
aber volkard hat wieder recht, in meinem fall bewirkt vector<vector> eine speicherfragmentierung, weil die daten, die wichtig behandelt werden, leider nicht hintereinanderliegen...
-
dgrat schrieb:
zynismus ist die sprache schwacher geister..
Naja, es ist ein wenig einfach, dem
vectormal grundsätzlich die Schuld in die Schuhe zu schieben, weil man persönliche (wahrscheinlich noch unbegründete) Abneigungen besitzt.dgrat schrieb:
aber volkard hat wieder recht, in meinem fall bewirkt vector<vector> eine speicherfragmentierung, weil die daten, die wichtig behandelt werden, leider nicht hintereinanderliegen...
Dann benutzt du eben nicht
memcpy(). Sobald nämlich mehr als nur PODs vorliegen, erzielst du damit undefiniertes Verhalten.Und dass ein verschachtelter
std::vectornicht alle Elemente linear hintereinander im Speicher halten kann, dürfte zu erwarten sein. Entweder man kopiert die inneren Container einzeln oder benutzt einen anderen Aufbau der Datenstruktur (eindimensionalerstd::vector).