C ++ std :: vector <std :: string> iterator segfaults </std :: string>

时间:2014-09-15 01:20:16

标签: c++ string c++11 vector iterator

我在迭代文件名向量时遇到了这个段错误。 std :: vector由另一个在相当混乱的代码中读取csv的函数填充。所以我把它缩小到下面的代码导致问题。

向量segfaults的迭代器,它产生了带有4个项的向量的第一个(有时是更晚的)项。推送第5项修复了问题。奇怪?矢量的迭代器工作正常。

#include <iostream>
#include <vector>

using namespace std;

std::vector<int> popbar() {
    // populate vector of integers
    //
    std::vector<int> bar;

    for(int i = 1; i < 6; i++)
        bar.push_back(i);

    return bar;
}

std::vector<std::string> popxar() {
    // populate vector of strings
    //
    std::vector<std::string> xar;

    xar.push_back("one");
    xar.push_back("two");
    xar.push_back("three");
    xar.push_back("four");
    // this line fixes segfault
    //xar.push_back("five");

    return xar;
}

void foo () {
    // yield next vector item
    //
    //auto bar = popbar();
    auto bar = popxar();

    //static auto itx = bar.begin();
    static vector<string>::iterator itx = bar.begin();

    if (itx == bar.end()) {
        cout << "end of line" << endl;
        itx = bar.begin();
    }

    cout << *itx++ << endl;
}

int main() {
    for(int i = 0; i < 11; i++) {
        foo();
    }
}

预期输出

one
two
three
four
end of line
one
two
three
four
end of line
one
two
three

我得到的输出是

one
Segmentation fault

也见过

one
two
three
Segmentation fault

one
three
three
���1������������1one1fourSegmentation fault

如果这让它更有趣。可以?请将此视为矢量。

2 个答案:

答案 0 :(得分:10)

您将静态迭代器定义为本地变量。你期望会发生什么?

foo返回时,本地向量xar将被销毁,这会使所有迭代器无效。重新输入foo会创建一个全新的向量,然后尝试使用无效的迭代器。随之而来的是未定义的行为。

答案 1 :(得分:4)

这是因为你有一个static迭代器指向一个非静态局部变量。当foo函数返回时,bar被破坏。这会导致undefined behavior