Absturz bei std::vector->erase()
-
Hallo,
ich habe folgende Funktion:
ivec4 Atlas::getRegion(const size_t width, const size_t height) { [...] ivec3 *node, *prev; ivec4 region = {{0, 0, width, height}}; std::vector<ivec3>::iterator i, bestIndex; [...] bestIndex = this->nodes->begin() - 1; [...] for( i = this->nodes->begin(); i != this->nodes->end(); ++i ) { y = this->fit(i, width, height); if( y >= 0) { node = &*i; if( (y + height) < (bestHeight) || ( ( (y + height) == bestHeight) && (node->z < bestWidth) ) ) { bestHeight = y + height; bestIndex = i; bestWidth = node->z; region.x = node->x; region.y = node->y; } } } if( bestIndex == this->nodes->begin()+1 ) { region.x = -1; region.y = -1; region.width = 0; region.height = 0; return region; } node->x = region.x; node->y = region.y; node->z = width; this->nodes->insert(bestIndex, *node); for(i = bestIndex + 1; i != this->nodes->end();) { node = &*i; prev = &*(i-1); if(node->x < (prev->x + prev->z)) { int shrink = prev->x + prev->z - node->x; node->x += shrink; node->z -= shrink; if(node->z <= 0) { i = this->nodes->erase(i); // Absturz --i; } else { ++i; break; } } else break; } return region; }Definition ivec3:
typedef union { int data[3]; int rgb[3]; int xyz[3]; int xy[2]; struct { int x; int y; int z; }; struct { int width; int height; int depth; }; struct { int r; int g; int b; }; struct { int red; int green; int blue; }; } ivec3;Definition ivec4:
typedef union { int data[4]; int xyzw[4]; int rgba[4]; int rgb[3]; int xyz[3]; struct { int x; int y; int z; int w; }; struct { int x_; int y_; int width; int height; }; struct { int r; int g; int b; int a; }; struct { int red; int green; int blue; int alpha; }; } ivec4;Definition this->nodes:
std::vector<ivec3> *nodes;Mein Problem ist nun, dass mein Programm an der kommentierten Stelle abstürzt (--i wird nicht mehr aufgerufen). Eine Internetrecherche zu dem Thema hat nichts ergeben, ebenso die Forensuche. I.d.R. haben die Leute den Iterator in der for-Schleife inkrementiert, das trifft in meinem Fall aber nicht zu. Irgendwelche Ideen? Danke schonmal im Voraus.
MfG
-
1. Debuggt?
2.this->kannst du weglassen,
4. und sieh mal ob das eine gültige Aktion ist, was du da machst (denn vielleicht zeigtija aufend(), usw. hab mir den Code nicht ganz durchgelesen)
-
Hacker schrieb:
1. Debuggt?
Hätte ich mal machen sollen, bevor ich das hier einstelle... Offenbar ist schon im Vorfeld in anderen Funktionen einiges schiefgelaufen.
this->kannst du weglassen,
Weiß ich. Es ist (meiner Meinung nach) so aber übersichtlicher.
4. und sieh mal ob das eine gültige Aktion ist, was du da machst (denn vielleicht zeigt
ija aufend(), usw. hab mir den Code nicht ganz durchgelesen)Siehe oben. Ich muss erstmal die Fehler vorher untersuchen.
-
Also, ich konnte die Fehler außerhalb der Funktion abstellen. Problematisch wird es jetzt wieder innerhalb, und zwar an dieser Stelle:
[...] this->nodes->insert(bestIndex, *node); for( i = bestIndex + 1; i != this->nodes->end();) { node = &*i; prev = &*(i-1); [...]Genauer gesagt im Kopf der for-Schleife. Der Debugger wirft hier "vector iterators incompatible" aus, offenbar wird einer der beiden Iteratoren vorher verändert. Mir ist aber nicht ganz klar, wo in der Funktion das geschehen sollte.
-
Ich push das nochmal hoch, weil ich immer noch keine Lösung habe.
-
Reduziere Codebeispiele auf das Wesentliche
Oder hilf uns deinen Algorithmus zu verstehen. Das kannst du unter anderem auch dadurch erreichen, dass du deine Funktion
Atlas::getRegionin kleinere Funktionen aufteilst, deren Namen eine Aussage darüber machen, was sie tun. Damit kann man dann jeden einzelnen Schritt im Algorithmus besser nachvollziehen und somit verstehen, was eigentlich gemacht wird.Zudem ist es immer praktisch, wenn du ein Beispiel präsentierst, welches kompilierbar ist und den Fehler aufweist. Damit wir allenfalls selber den Debugger anwerfen können.
Grüssli
-
Du weiß schon, dass die insert und erase Methoden von vector unter ( meisten ) Umständen alle deine vorher gespeicherten Iteratoren ungültig machen... oder???