使用std :: vector的奇怪分段错误

时间:2012-12-16 15:12:54

标签: c++ stl segmentation-fault

看一下这个片段:

#include <string>
#include <iostream>
#include <vector>

using namespace std;

class base {
public:
  string foo;
  base() {};
  base(const base &orig) {
    this->foo = orig.foo;
  };
 ~base() {} ;
};

class derived : public base {
public:
  string bar;
  derived(const derived &orig) : base(orig) {
    this->bar = orig.bar;
  }
  derived() : base() {} ;
  ~derived() {};
};

void asd(derived d)
{
    // works fine
    cout << d.foo << d.bar << endl;
}

int main(void)
{
    vector<derived> v;

    derived bla;

    bla.foo = "Test ";
    bla.bar = "String ";

    v.push_back(bla);

    asd(bla);

    // Why the hell does v.end()->foo and v.end()->bar segfault?!
    cout << v.end()->foo;
    cout << v.end()->bar << endl;
}

为什么会出现分段错误?这是控制台输出 (用g ++ -o test test.cpp -g编译)

./test
Test String 
zsh: segmentation fault  ./test

派生类v.end()的this指针没有指向正确的位置...... 但为什么呢?

2 个答案:

答案 0 :(得分:13)

end()不是指向最后一个元素的迭代器。它指向一个过去的最后一个元素。取消引用end()是非法的。

如果您想要最后一个元素,请使用back()

答案 1 :(得分:3)

你的问题是使用v.end()。

引自here

将迭代器返回到结尾 返回一个迭代器,引用向量容器中的past-the-end元素。

过去结束元素是跟随向量中最后一个元素的理论元素。它没有指向任何元素,因此不应被解除引用。

因为标准库的函数使用的范围不包括其闭合迭代器指向的元素,所以此函数通常与vector :: begin结合使用以指定包含容器中所有元素的范围。

如果容器为空,则此函数返回与vector :: begin。

相同的内容

使用v [0]代替。 (对于此特定测试,请参阅引用页面中有关矢量获取者的其他建议。)