Löschen des letzten Elementes aus einem Vector schlägt fehl!!
-
Hi,
ich versuche ein Objekt aus einem vector zu löschen! Dabei handelt es sich um das letzte objekt. doch genau da schmiert bei mir das Programm gnadenlos ab:
for (std::vector<CItem>::iterator it = this->m_vec_Items.begin(); it != this->m_vec_Items.end(); ++it) { if (this->m_Player.collidesWith(*it)) { switch (it->getType ()) { case HEALTH: { blob = true; this->m_vec_Items.erase (it); } break; default : break; } } }
-
Du solltest it nur inkrementieren, wenn du nicht erase aufruft.
CItem? m_vec_Items? Wie war Shades URL zu dem Thema?
-
iterator erase(iterator it);
liefert den Iterator welche hinter das entfernte Element zeigt oder end wenn keine Elemente danach vorhanden sind.
-
operator void schrieb:
Du solltest it nur inkrementieren, wenn du nicht erase aufruft.
CItem? m_vec_Items? Wie war Shades URL zu dem Thema?
Also der Prefix "m_" für Membervariablen ist imho Geschmackssache/Glaubensfrage. Das C als Prefix, naja. Ich habe es in der Vergangenheit manchmal auch davor gesetzt um zu zeigen, dass die Klasse MFC-haltig, sprich nicht portierbar ist. Mache das seit ca. einem Jahr aber auch nicht mehr, da die meisten Klassen in denen ich die MFC verwende so speziell sind (meist irgendein UI-Kram), dass ich sie eh nicht portieren möchte.
EDIT: Uh, das war jetzt mal derbst offtopic
.
-
Kann mich mal jemand über den sinn dieser Switchanweisung aufklären?
switch (it->getType ()) { case HEALTH: { blob = true; this->m_vec_Items.erase (it); } break; default : break; }
ein einfaches
if (it->getType () == HEALTH) { blob = true; this->m_vec_Items.erase (it); }
tut es doch auch.
Und wie bereits gesagt, durch erase werden sämtliche Iteratoren auf den vector ungültig.
-
wenn schon nen getType(), dann sicher fuer mehr als einen Type,
hat sicher nur die (...) vergessen
-
MaSTaH schrieb:
Also der Prefix "m_" für Membervariablen ist imho Geschmackssache/Glaubensfrage.
Das meinte ich auch nicht, nur die anderen beiden
-
Helium schrieb:
Und wie bereits gesagt, durch erase werden sämtliche Iteratoren auf den vector ungültig.
upsa dann darf man:
map<int,int> testmap; for(map<int,int>::iterator i=testmap.begin();i!=testmap.end();++i) { if(i->second==a) testmap.erase(i); else if(i->second>a) i->second-=1; }
wohl auch nicht, was?
wie mach ich denn das am besten? nach dem löschen nochmal neu mit der schleife beenden? also eigentlich hat es so funktioniertgrüsse steve
-
Setze i einfach auf den Iterator, den erase zurückgibt. Dann sollte es korrekt sein.
-
er benutzt switch glaube ich weil es Atens mehr Obejekte sein sollen und Btens schneller ist als IF und IF ELSE
-
und Btens schneller ist als IF und IF ELSE
Quatsch.
-
Helium schrieb:
Setze i einfach auf den Iterator, den erase zurückgibt. Dann sollte es korrekt sein.
erase gibt n iterator zurück? cool
bis jetzt hat ichs in ner schleife gemacht, die nach dem löschen wieder auf begin() springt.. thx!grüsse steve
/edit:
hm aber wenn ichs in der schleife auf den iterator setze, dann wird er ja schon beim nächsten durchlauf der schleife wieder incrementiert, also ich bin einen zuweitich könnte natürlich den iterator auf *rückgabeiteratorvonerase*-1 setzen, aber dann hab ich ja möglicherweise einen iterator, der kurzzeitig noch vor begin() zeigt wenn der rückgabewert=begin() ist
/edit2:
irgendwie gibt bei mir erase auch keinen iterator zurück
-
for (map<int,int>::iterator i=testmap.begin(); i!=testmap.end();) { if (i->second==a) i = testmap.erase(i); else if (i->second>a) { i->second-=1; ++i; } else ++i; }
-
jo darauf bin ich dann auch gekommen... blos wenn erase kein iterator zurückgibt
-
i = testmap.erase(i);
Das wird nicht gehen, denn erase gibt bei maps, anders als bei Vector, nicht das nächste Element wieder. Der Iterator ist ungültig.
testmap.erase(i++);
So gehts....
-
hm *hust* ich glaub mein dev-cpp spinnt:
no match for ` std::_Rb_tree_iterator<std::pair<const varray::key, int>, std::pair<const
candidates are: std::_Rb_tree_iterator<std::pair<const varray::key, int>, std::pair<const
im vc6 gehts...
grüsse steve
-
CarstenJ schrieb:
i = testmap.erase(i);
Das wird nicht gehen, denn erase gibt bei maps, anders als bei Vector, nicht das nächste Element wieder. Der Iterator ist ungültig.
testmap.erase(i++);
So gehts....
jetzt bin ich verwirrt....
müsste es nicht eher testmap.erase(i--); heissen, sonst überspring ich doch 2 wertegrüsse steve
-
Ups, entschuldigung, ich hab gerade an einen vector gedacht
-
müsste es nicht eher testmap.erase(i--); heissen, sonst überspring ich doch 2 werte
Nein, eben das genau nicht. Du überspringst praktisch nur eine Stelle, und zwar die, die du mit erase gelöscht hast. Damit zeigt der Iterator auf die nächste Stelle und ist somit wieder gültig.
-
naja ich dachte es rückt vielleicht auf...
irgendwie bin ich aber bei dem code in ne endlosschleife geraten
grüsse steve