2016-07-25 5 views
1

Я изучаю C++, и у меня есть проблема с ошибкой сегментации. В моем проекте я хочу прочитать из файла в 2d-вектор char. Вектор является std::vector<std::vector<char>> gamearea;Ошибка сегментации в push_back для 2d-вектора

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++; 
    } 
} 

Это моя функция чтения файла и отладчик (я использую GDB) говорит по push_back является ошибкой сегментации.

Может кто-нибудь мне помочь? Я не могу найти проблему.

+2

'gameArea [i] .push_back (строка [j])' - измените это на 'gameArea.at (i) .push_back (строка [j])', и не удивляйтесь, если вы сейчас получите исключение out_of_range' вместо ошибки сегментации. Другими словами, нет 'gameArea [i]', поскольку 'i' является недопустимым индексом. – PaulMcKenzie

+0

Можете ли вы объяснить мне, почему я недействительный индекс и что мне нужно изменить? Я хочу сохранить в Vector строки игрового поля и в других функциях мне нужно точное положение вещей в игре, как на рисунке и в блоках. Я думал, что могу сказать с i строкой, и с линией [j] сохранить символ в векторе, чтобы я знал строку и столбец символа. – Lisa

ответ

3

Вы должны сначала отодвигают в первый вектор а std::vector<char>, потому что по умолчанию вектор gamearea пуст, поэтому при обращении к gamearea [я] вы в конечном итоге доступа вне границ (с gamearea имеет 0 элементов внутри него)

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

Хорошо, спасибо, что больше не существует ошибки сегментации, но в векторе ничего не сохраняется. Я что-то забыл, чтобы сохранить содержимое файла в этом векторе? – Lisa

+0

какой вектор не сохраняется? вы уверены, что j увеличивается? – MichaelCMS

+0

думаю. Но я видел в отладчике, что после std :: vector curArea; что-то вроде этого happend '305 \t std :: vector curArea; (GDB) шаг станд :: вектор <символ, станд :: Распределитель > :: вектор (это = 0x7fffffffe1a0) при /usr/include/c++/4.9/bits/stl_vector.h:257 : _Образы базовой () {} (GDB) шаг станд :: _ Vector_base <символ, станд :: распределитель > :: _ Vector_base (это = 0x7fffffffe1a0) на /usr/include/c++/4.9/bits/stl_vector.h:125 : _M_impl() {} ', и я не уверен, что это говорит мне о том, что он не входит в цикл for. – Lisa

0

Вот пример правильного чтения в и обновлении вектора, учитывая, что он пуст:

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

Примечание. Нам не нужно тестировать eof(). Кроме того, все, что нам нужно сделать, это вызвать push_back всю строку данных, используя два аргумента std :: vector constructor, который принимает два итератора.

+0

Хорошо, я думаю, что это работает, но я не получил область на моей консоли, когда моя функция show() вызывается в Main и когда я вхожу в отладчик примерно так: 'std :: vector > :: vector <__ gnu_cxx :: __ normal_iterator , void> ( this = 0x7fffffffe1c0, __first = 35 '#', __last = 0 '\ 000', __a = ...) at /usr/include/c++/4.9/bits/stl_vector.h:403 \t: _Base (__ a) 'произойдет, и я не знаю, что здесь происходит. Я не очень-то разбираюсь в отладчике. – Lisa

+0

См. Мой пример. Вход считывается и присваивается правилу gamearea 2d. – PaulMcKenzie