使用列表迭代器时出现分段错误

Segmentation error with a list iterator

本文关键字:分段 错误 列表 迭代器      更新时间:2023-10-16
class Line{
    list<char> line;
    char getChar(const int position) const {
         std::list<char>::const_iterator itr;
         itr = line.begin();
         for (int i = 0; i< position; i++){
            itr++;
         }
         return *itr;//according to the debugger this is where the error happens.
}

所以这是一个在我的程序中被称为LOT的函数,然而在一个特定的实例中,它被调用并导致分割错误。是什么原因导致的呢?

这就是它的名字:

    std::list<Line>::const_iterator itr;
    itr = file.begin();// file is a list of Lines, line 1 characters 0-4 are all spaces.
    while (itr != file.end()) {
         int i = 0;//this works with 0 but anything else it gets a segmentation error.
        while ((*itr).getChar(i) != 'n') {//This is where it errors.

这是一些已经出现了几次,但对于我的生活,我不记得我是如何解决它。我只是不明白当这个函数在极其相似的情况下多次调用时,它是如何得到这样的错误的。

如果文件中有一行只有换行符,这将导致分段错误。如果你传入1,它会尝试访问行中位置1的东西。但是n字符在位置0

如果您的第一行是一个空格,那么一旦您在实现中获得索引(i)超过0,您就会得到分段错误。将迭代器推进到容器的长度之外(超过列表的末尾)。

你可以使用一些标准的STL,它会抛出一个异常,只要你超越了容器的结束(这将给你更多的信息,一个seg错误):

class Line{
    list<char> line;
    char getChar(const int position) const {
        auto itr = line.begin();
        advance(itr,position);    
        return (*itr);        
    }
}; 

如果您不使用c++ 11,将auto更改为std::list<char>::iterator。如果你想无声地阻止客户端获得超出结束的位置(我不建议):advance(itr,(position > line.size()-1) ? line.size()-1 : position);(也可能想检查该位置是正的或使其为unsigned int)。

我也不知道你为什么要使用list,除非你做了很多跨线拼接。如果你的行包含很多字符,我建议使用vector<char>(如果你知道长度,使用reserve),或者简单地使用std::string

string abcd = "abcd";    
cout << abcd.at(0) << endl;
cout << abcd[0] << endl;
cout << abcd.at(4) << endl;

异常将更有用:

libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string