[Solved] Sichere referenzen auf std::vector
-
Hi!
Eine Referenz zu einem vector wird schlichtweg ungültig wenn der Vector durch befüllen entscheidet sich an einen anderen Ort im Speicher zu verlegen.
Aber Wie soll ich einer Funktion eine Referenz auf einen Vector übergeben wenn eben diese Referenz nach genügent langem befüllen in der selben funktion noch "kaputt" geht...
Bzw was soll man dagegen machen?Hier ist er zuletzt ausgeführte Code mit dem Fehler unten als Kommentar:
ErrType method(StreamDataBlock& sDB, StreamPlotable& sPlotable) { StreamSubDataBlock* sSDB; if(sDB.getSubData(sSDB, FIRST) == _ErrType::Success) { //p auf Constante Daten in sSDB speichern if(sSDB->isValid()) { int size = (int)(sSDB->getDataSize() / (sizeof(RawData))); RawData* raw = reinterpret_cast<_ODM_RawData*>(sSDB->getpOfData()); int sSPIndex = sPlotable.addReturnIndexNewElement(); // index in vectoren bleibt immer konstant for(int i = 0; i < size; ++i, ++raw ) { int index = sPlotable.getElement(sSPIndex).addReturnIndexNewGraph(); for(int j = 0; j < PIXELS_PER_SCAN; j++) { sPlotable.getElement(sSPIndex).getGraphPlotables()->at(index).addPoint(raw->m_Pixels[j], j); // << throw ex } } } return ErrType::Success; } else { return ErrType::Failure; } } // die Funktion addPoint ist sehr Simpel: void _GraphPlotable :: addPoint(double y, double x) { m_y.push_back(y); //double vector m_x.push_back(x); //double vector // Dieses Pushback führt manchmal zu diesem Gang und wirft exceptions: // // Prog.exe!GraphPlotable::addPoint(double y, double x) Zeile 11 C++ // Prog.exe!std::vector<double,std::allocator<double> >::push_back(const double & _Val) Zeile 1199 C++ // FDSA.exe!std::vector<double,std::allocator<double> >::_Reserve(unsigned __int64 _Count) Zeile 1532 C++ // FDSA.exe!std::vector<double,std::allocator<double> >::_Reallocate(unsigned __int64 _Count) Zeile 1519 C++ // msvcp110d.dll!std::_Container_base12::_Orphan_all() Zeile 216 C++ // das hier ist die "Finale" Fehlermeldung: // Unbehandelte Ausnahme bei 0x000007FEE9FC308F (msvcp110d.dll) in Prog.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xFFFFFFFFFFFFFFFF }
-
cl90 schrieb:
Eine Referenz zu einem vector wird schlichtweg ungültig wenn der Vector durch befüllen entscheidet sich an einen anderen Ort im Speicher zu verlegen.
Nein.
Referenzen auf die Elemente des vector werden ungültig.
-
Ok, das ist schonmal besser.
Aber gerade dann versteh ich das Problem nicht.
-
Dann zeig doch mal ein Minimalbeispiel, das das Problem reproduziert.
Ich habe ja getElement oder getGraphPlotables im Verdacht.
-
SubStreamPlotable& StreamPlotable :: getElement(int index) { return m_SubPlotables.at(index); } vector<_GraphPlotable>* SubStreamPlotable :: getGraphPlotables() { return &(m_Graphs); }
Ein Minibeispiel ist schwierig da ich da ziemlich viele Rohdaten durchjagen muss damit ich überhaupt dieses Problem bekomme.
Wie gesagt es funktioniert grundsätzlich, und manchmal kommt eben dieses Problem.Was ist eigentlich wenn ich einen Vector von Objekten habe die Vectoren haben?
Also z.b.
StreamPlotable hat einen Vector mit SubStreamPlotables.
und SubStreamPlotables haben einen vector zu GraphPlotables.Du sagtest der Zeiger auf den Vector von StreamPlotable wird immer valide sein.
Wird auch ein Zeiger auf den Graphplotable vector valide bleiben wenn der vector von StreamPlotable beschließt umzuziehen?
-
cl90 schrieb:
Wie gesagt es funktioniert grundsätzlich, und manchmal kommt eben dieses Problem.
Manchmal im Sinne von: Mal kommt es, mal nicht, und nicht immer an derselben Stelle?
Sind noch andere Threads im Spiel?
-
ja... jetzt wo dus sagst...
Verdammt.. Ich hab die kritischen Bereiche in den Threads gesichert aber hab ganz vergessen das dieses Verkettung von Funktionen noch Nicht Thread sicher ist...
Und jetzt wo ich darüber nachdenke, passiert es häufig, wenn ich zu den Thread events noch weitere events feuere....Danke!!!
Endlich hab ich wieder eine heiße Spur...edit:
Kritischer Bereich gesichert; Fehler ist seither nicht mehr aufgetretten
Ich denke das wars... Tausend Dank für den richtigen Tipp!