2016-07-25 66 views
1

我正在学习C++,并且遇到了分段错误问题。在我的项目中,我想从一个文件读入char的二维矢量。 矢量是std::vector<std::vector<char>> gamearea;2d向量push_back中的分段错误

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(line [j])' - 将此更改为'gameArea.at(i).push_back(line [j])',如果您现在得到'out_of_range'异常,而不是分段错误。换句话说,没有'gameArea [i]',因为'i'是一个无效索引。 – PaulMcKenzie

+0

你能告诉我为什么我是一个无效索引,我需要改变什么?我想在向量中保存游戏区域的行,并且在其他功能中,我需要游戏中的事物的确切位置,如图和框。我认为我可以用行来说,它和行[j]保存在矢量中的字符,以便我知道字符的行和列。 – Lisa

回答

3

您需要首先推回到所述第一矢量a std::vector<char>因为缺省情况下gamearea向量是空的,所以访问gamearea当[I]你最终访问超出范围(因为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

好的,谢谢你知道没有分割错误了,但它并没有保存Vector中的任何东西。我忘了一些东西来保存这个向量中的文件的内容? – Lisa

+0

哪些矢量未保存?你确定j递增? – MichaelCMS

+0

我这么认为。但我在调试器中看到std :: vector curArea后;像这样的事情'305 \t std :: vector curArea;在/usr/include/c++/4.9/bits/stl_vector.h:257 :_Base((gdb)step std :: vector > :: vector(this = 0x7fffffffe1a0) ){} (GDB)步骤 的std :: _ 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()。此外,我们需要做的是使用两个参数std :: vector构造函数调用push_back整个数据串,该构造函数需要两个迭代器。

+0

好吧我认为它的工作,但我没有得到我的控制台上的区域时,我的show()函数在主中调用,当我在调试器中像这样:'std :: vector > :: vector <__ gnu_cxx :: __ normal_iterator ,void>( this = 0x7fffffffe1c0,__first = 35'#',__last = 0'\ 000',__a = ...)在/usr/include/c++/4.9/bits/stl_vector.h:403 \t:_Base(__ a) '会发生,我不知道这里发生了什么。我并不习惯理解调试器。 – Lisa

+0

查看我的示例,输入被读入并正确地分配给gamearea 2d向量。 – PaulMcKenzie