看一下这个片段:
#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指针没有指向正确的位置...... 但为什么呢?
答案 0 :(得分:13)
end()
不是指向最后一个元素的迭代器。它指向一个过去的最后一个元素。取消引用end()
是非法的。
如果您想要最后一个元素,请使用back()
。
答案 1 :(得分:3)
你的问题是使用v.end()。
引自here
将迭代器返回到结尾 返回一个迭代器,引用向量容器中的past-the-end元素。
过去结束元素是跟随向量中最后一个元素的理论元素。它没有指向任何元素,因此不应被解除引用。
因为标准库的函数使用的范围不包括其闭合迭代器指向的元素,所以此函数通常与vector :: begin结合使用以指定包含容器中所有元素的范围。
如果容器为空,则此函数返回与vector :: begin。
相同的内容使用v [0]代替。 (对于此特定测试,请参阅引用页面中有关矢量获取者的其他建议。)