problem mit std::list
-
ich dachte bisher, das list-iteratoren nur bei erase oder splice ungültig werden können, insbesondere dass end konstant wärend der ganzen lebenszeit einer liste ist. nachdem diese annahme allerdings zu einem crash-problem geführt hat, bin ich jetzt nicht mehr so sicher:
zumindest die dinkumware implementation von vc++7.1 invalidiert end wenn list::sort verwendet wird.
frage: ist das standardkonform oder (noch) ein fehler von vc?
-
Ich würde nicht annhmen, dass jeder Iterator immer gültig ist. Selbst end() muss meiner Meinung nach nicht immer gültig sein.
std::list::sort() dagegen darf keinen Iterator invalidieren. Das wäre also ein Bug.
Hast du Beispielcode, der das Problem zeigt?
-
Der Standard sagt, dass erase, pop_back, pop_front und clear nur Iteratoren und Referenzen auf die gelöschten Elemente invalidieren (23.2.2.3-3) und splice in seiner 2 Parameter-Form alle Iteratoren der übergebenen Liste (23.2.2.4-4) und in seinen anderen beiden Formen nur Iteratoren der gesplicten Elemente.
Die Dinkumware-Impl. war zumindest beim 6er VC++ grausig. Vom 7er hatte ich das noch nicht gehört (muss aber nicht zwingend was heißen).
-
ein bisschen code zum demonstrieren:
#include <iostream> #include <list> using namespace std; int main() { std::list< int > l; typedef std::list< int >::iterator iterator; l.push_back( 10 ); l.push_back( 1 ); l.push_back( 3 ); l.push_back( 7 ); l.push_back( 5 ); l.push_back( 0 ); for ( iterator i = l.begin(); i != l.end(); ++i ) std::cout << *i << '\t'; iterator end1 = l.end(); std::cout << "\nend = " << *(size_t*)&end1 << '\n'; l.sort(); for ( iterator i = l.begin(); i != l.end(); ++i ) std::cout << *i << '\t'; iterator end2 = l.end(); std::cout << "\nend = " << *(size_t*)&end2 << '\n'; std::cout << ( end1 == end2 ) << '\n'; char x; std::cin >> x; }mit vc++2005 geht alles problemlos - die implementation ist identisch bis auf eine zeile - offenbar haben die programmierer den fehler dort auch gefunden.
naja, das wär dann noch so eine sache bei der man bei vc++7.1 aufpassen muss... aber das ist bei ms ja normal:
der auto_ptr funktioniert im 8er vc immer noch nicht richtig :p