2015-07-09 8 views
6

Ich erstelle eine Karte nur zu Lernzwecken, um einige Schlüsselwertpaare zu speichern. Wenn ich das zweite Feld der Karte unter Verwendung begin() Funktion drucke, kann ich das zweite Feld der Karte drucken, aber wenn ich versuche, dasselbe mit dem letzten Element der Karte unter Verwendung end() zu tun, kann es das zweite Feld nicht drucken. Unten ist mein Code:Konnte zweites Feld der Karte nicht mit end() erhalten

#include <iostream> 
#include <cstdlib> 
#include <map> 
#include <string> 
#include <stdio.h> 


using namespace std; 

map<int,std::string> arr; 

map<int,std::string>::iterator p; 

int main(int argc, char** argv) { 

    arr[1] = "Hello"; 
    arr[2] = "Hi"; 
    arr[3] = "how"; 
    arr[4] = "are"; 
    arr[5] = "you"; 

    p = arr.begin(); 
    printf("%s\n",p->second.c_str()); 

    p = arr.end(); 
    printf("%s\n",p->second.c_str()); 

    return 0; 

} 
+3

für STL-Container, ".end()" liefert einen Iterator zum "1-extend-the-end-Element" siehe auch: http: // stackoverflow.com/questions/15252002/what-is-the-past-the-end-iterator-in-stl-c – user2950911

Antwort

2

das letzte Element zu drucken, verwenden reverse iterator:

map< int,std::string>::reverse_iterator p; 
p = arr.rbegin(); 
if(p != arr.rend()) { 
    // Do whatever with, it points to the last element 
} else { 
    // map is empty 
} 

std::map::end den Iterator auf eine Vergangenheit letztes Element zurückkehren und es ist dereferencing nicht definiertes Verhalten.

Von std::map::end bei en.cppreference

Gibt einen Iterator auf das Element nach dem letzten Element des Behälter. Dieses Element fungiert als Platzhalter; Der Versuch, darauf zuzugreifen führt zu undefiniertem Verhalten.

1

std :: SOMETHING.end() nicht zurück das letzte Element, gibt es past-the-End-Element. Überprüfen Sie die C++ documentation. Im Wesentlichen versuchen Sie, den undefinierten Speicherort zu differenzieren.

6

Die Dereferenzierung end() ist undefined behavior, da end() einen Iterator auf 1 nach dem Ende der Map zurückgibt. Wenn Sie das letzte Element, dann können Sie

p = --arr.end(); 

verwenden Sie nicht

p = arr.rbegin() 

verwenden können, wie Sie nicht ein Reverse-Iterator zu einem vorderen Iterator zuweisen können (live example). Wenn Sie rbegin() verwenden möchten, müssen Sie einen umgekehrten Iterator erstellen.

map<int,std::string>::reverse_iterator rit; 
rit = arr.rbegin(); 

// or 

auto rit = arr.rebegin(); //C++11 or higher required for this 

Oder man kann es auf einen Vorwärts Iterator konvertiert this answer von visitor

Verwendung Wie immer sollten Sie überprüfen, um sicherzustellen, dass Sie eine gültige Iterator haben. Wenn der Container leer begin() == end() ist und Dereferenzierung ist nicht definiert Verhalten.

Quelle: http://en.cppreference.com/w/cpp/container/map/end

+1

"' begin() == end() '" - Ich denke 'arr.empty()' ist klarer . Es kann auch schneller sein. –

+0

@NO_NAME Ich habe gerade demonstriert, dass 'begin()' dasselbe ist wie 'end() 'wenn der Container leer ist. – NathanOliver

2

können Sie --arr.end() oder arr.rbegin() verwenden.

arr.end() gibt Iterator an das Element nach dem letzten Element zurück. Dies ermöglicht einfachere Schreib-Schleifen. Dieses Element dient nur zum Vergleichen. Dereferenzieren ist nicht erlaubt.

1

Wie bereits in anderen Posts erwähnt, end() ist ein Iterator eine Position nach dem letzten Element in der Karte. Also solltest du nicht versuchen, seine Felder zu bekommen. Um das letzte Element zu erhalten, können Sie rbegin() verwenden.

Verwandte Themen