2016-07-25 32 views
1

Ich lerne C++ und ich habe ein Problem mit einem Segmentierungsfehler. In meinem Projekt möchte ich von einer Datei in einen 2d Vektor von char lesen. Der Vektor ist std::vector<std::vector<char>> gamearea;Segmentierungsfehler in push_back für einen 2d Vektor

void Structure::readFile(const std::string filename) 
{ 
    std::ifstream file(filename.c_str()); 
    if (!file.is_open()) 
    { 
     std::cerr << "Error opening file: " << filename << std::endl;  
     exit(1); 
    } 
    std::string line; 
    int i = 0; 
    while (true) 
    { 
     std::getline(file, line); 
     if (file.eof()) 
     { 
      break; 
     } 
     for (size_t j = 0; j< line.length(); j++) 
     { 
      gamearea[i].push_back(line[j]); 
     } 
     i++; 
    } 
} 

Diese meine Lesedatei Funktion ist und der Debugger (I gdb) sagt von push_back ist ein Segmentierungsfehler.

Kann mir jemand helfen? Ich kann das Problem nicht finden.

+2

'gameArea [i] .push_back (line [j])' - ändere dies in 'gameArea.at (i) .push_back (line [j])', und sei nicht überrascht, wenn du jetzt ein 'out_of_range' Ausnahme anstelle eines Segmentierungsfehlers. Mit anderen Worten, es gibt kein 'GameArea [i]' da 'i' ein ungültiger Index ist. – PaulMcKenzie

+0

Können Sie mir erklären, warum ich ein ungültiger Index bin und was ich ändern muss? Ich möchte im Vector die Zeilen eines Spielbereichs speichern und in anderen Funktionen brauche ich die genaue Position der Dinge im Spiel wie die Figur und die Boxen. Ich dachte, ich könnte mit i sagen, mit der Zeile ist es und mit der Zeile [j] speichern Sie das Zeichen im Vektor, so dass ich die Zeile und die Spalte des Zeichens kenne. – Lisa

Antwort

3

Sie müssen zuerst zurück in den ersten Vektor schieben eine std::vector<char> da standardmäßig die gamearea Vektor leer ist, so dass, wenn gamearea Zugriff auf [i] Sie außerhalb der Grenzen Zugriff am Ende (da gamearea hat 0 Elemente im Inneren)

Hier
void Structure::readFile(const std::string filename) 
{ 
std::ifstream file(filename.c_str()); 
if (!file.is_open()) { 
std::cerr << "Error opening file: " << filename << std::endl; exit(1); 
} 
std::string line; int i = 0; 
while (true) { 
    std::getline(file, line); 
    if (file.eof()) { break; } 

    // NOTICE HERE 
    // We add a new vector to the empty vector 
    std::vector<char> curArea; 
    gamearea.push_back(curArea); 


    for (size_t j = 0; j< line.length(); j++) { 
     gamearea[i].push_back(line[j]); 
    } 
    i++; 
    } 
} 
+0

Ok, danke, dass es keinen Segmentierungsfehler mehr gibt, aber es speichert nichts im Vektor. Vergesse ich etwas, um den Inhalt der Datei in diesem Vektor zu speichern? – Lisa

+0

Welcher Vektor wird nicht gespeichert? Bist du sicher, dass j inkrementiert wird? – MichaelCMS

+0

Ich denke schon. Aber ich sah im Debugger, dass nach std :: vector curArea; so etwas passierte '305 \t std :: vector curArea; (GDB) Schritt std :: vector > :: vector (dies = 0x7fffffffe1a0) bei /usr/include/c++/4.9/bits/stl_vector.h:257 : _Base ({)} (gDB) Schritt std :: _ Vector_base > :: _ Vector_base (this = 0x7fffffffe1a0) bei /usr/include/c++/4.9/bits/stl_vector.h:125 : _M_impl() {} 'und ich bin mir nicht sicher, was das mir zwischen dem Ding sagt, dass es nicht in die for-Schleife geht. – Lisa

0

ist ein Beispiel für richtig beim Lesen und Aktualisieren des Vektors, da es leer ist:

void Structure::readFile(const std::string filename) 
{ 
    std::ifstream file(filename.c_str()); 
    if (!file.is_open()) { 
     std::cerr << "Error opening file: " << filename << std::endl; 
    return; 

    std::string line; 
    while (std::getline(file, line)) 
     gamearea.push_back(std::vector<char>(line.begin(), line.end())); 
} 

Live Example

Hinweis: Wir müssen nicht auf eof() testen. Alles, was wir tun müssen, ist push_back eine ganze Reihe von Daten unter Verwendung des std. :: vector -Konstruktors mit zwei Argumenten aufzurufen, der zwei Iteratoren benötigt.

+0

Ok Ich denke, es funktioniert, aber ich habe nicht den Bereich auf meiner Konsole, wenn meine Show() -Funktion im Main aufgerufen wird und wenn ich im Debugger etwas wie folgt gehen: 'std :: vector > :: vector <__ gnu_cxx :: __ normaler_iterator , void> ( dies = 0x7fffffffe1c0, __first = 35 '#', __last = 0 '\ 000', __a = ...) at /usr/include/c++/4.9/bits/stl_vector.h:403 \t: _Base (__ a) 'wird passieren und ich weiß nicht, was hier los ist. Ich bin nicht wirklich gewohnt, den Debugger zu verstehen. – Lisa

+0

Siehe mein Beispiel, Die Eingabe wird eingelesen und dem Spielbereich 2d Vektor korrekt zugewiesen. – PaulMcKenzie