Warum SegFault
-
Hallo,
folgender kleiner Beispielcode
#include <map> #include <vector> #include <string> #include <iostream> int main() { std::map<int, std::vector<std::string> > mp; for(int i = 0; i < 10; ++i) { std::vector<std::string> vc; vc.push_back("A"); vc.push_back("B"); vc.push_back("C"); vc.push_back("D"); vc.push_back("E"); mp[i] = vc; } for(std::map<int, std::vector<std::string> >::iterator iter = mp.end(); iter != mp.begin(); --iter) { for(std::vector<std::string>::iterator iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) { if(*iter2 == "C") { std::cout << *iter2 << std::endl; break; } } } return 0; }Ich weiß, dass dieser Code nichts sinnvolles macht. Ich denke jedoch, dass er korrekt ist. Allerdings führt er - unter Windows mit Codeblocks immer und unter Ubuntu 9.04 manchmal(?) - zu einem Segmentation Fault in Zeile 26. Wo ist da der Denkfehler?
Danke
-
reverse_iterator und rend und rbegin sind ein paar stichworte.
denn end() liefert einen ungültigen iterator
-
Danke für die Antwort. Aber wieso funktioniert es denn dann manchmal trotzdem? In einem anderen Anwendungsfall, in dem ich allerdings auch durch die map von Hinten iteriere, habe ich unter Ubuntu nie Probleme und unter XP funktioniert es manchmal und manchmal nicht. Zufall?
-
mp.end() liefert dir nicht einen Iterator, welcher auf das letzte Element verweist, sondern auf das Element hinter dem letzten. Der Iterator, welcher von mp.end() zurückgeliefert wird, darf man auf gar keinen Fall dereferenzieren.
Was du suchst sind Reverse Iteratoren. Die bekommt man über rbegin und rend. Das ganze sieht dann zum Beispiel so aus:
#include <vector> int main() { std::vector<char> vec; vec.push_back('h'); vec.push_back('e'); vec.push_back('l'); vec.push_back('l'); vec.push_back('o'); std::vector<char>::reverse_iterator iter = vec.rbegin(); std::vector<char>::reverse_iterator end = vec.rend(); for(; iter != end; ++iter) // man bemerke, hier wird inkrementiert { std::cout << *iter; } return 0; }Referenzen,
reverse_iterator:
http://www.cplusplus.com/reference/std/iterator/reverse_iterator/Standardbibliothek Container:
http://www.cplusplus.com/reference/stl/Zum Beispiel
std::map::rbeginundstd::map::rend:
http://www.cplusplus.com/reference/stl/map/rbegin/
http://www.cplusplus.com/reference/stl/map/rend/(In der Vorschau gesehen, etwas zu spät, aber noch zur anderen Frage)
Es ist undefiniertes Verhalten -> Es kann alles passierenGrüssli
-
basti33 schrieb:
Danke für die Antwort. Aber wieso funktioniert es denn dann manchmal trotzdem? In einem anderen Anwendungsfall, in dem ich allerdings auch durch die map von Hinten iteriere, habe ich unter Ubuntu nie Probleme und unter XP funktioniert es manchmal und manchmal nicht. Zufall?
Das ist die Essenz des Wörtchens "undefiniertes Verhalten". Undefiniert heißt eben es kann alles passieren, wenn der Compiler (und die Implementatoren der Bibliothek) wollen können sie bei undefiniertem Verhalten eine Exception schmeißen oder einfach gucken was passiert (wie in deinem Fall) oder deine Festplatte plattbügeln, dir einen Strauß Rosen schicken, anfangen Rätselspiele zu treiben was du wohl eigentlich tun wolltest usw...