Кодекса перечислены ниже вызывает ошибку сегментации в петле на основе итератора:вина Сегментация итератора разыменования
#include <iostream>
#include <vector>
class A {
public:
A(unsigned id = 0) {id_ = id;}
unsigned get_id() {return id_;}
private:
unsigned id_;
};
class B {
public:
B() {}
B(std::vector<A*> entries) : entries_(entries) {}
const std::vector<A*> get_entries() const {
return entries_;
}
private:
std::vector<A*> entries_;
};
int main() {
std::vector<A*> entries;
for (unsigned i = 0; i < 5; i++) {
entries.push_back(new A(i));
}
B b(entries);
// index based access (ok)
for (unsigned i = 0; i < b.get_entries().size(); i++) {
std::cout << b.get_entries()[i]->get_id() << std::endl;
}
// iterator based access (segmentation fault)
for (std::vector<A*>::const_iterator i = b.get_entries().begin();
i != b.get_entries().end();
++i) {
std::cout << (*i)->get_id() << std::endl;
}
}
С другой стороны, индекс на основе цикла работает нормально.
Это поведение срабатывает, когда возвращается копия std::vector
(см.: const std::vector<A*> get_entries() const
), а не ссылка const
на нее, например. const std::vector<A*>& get_entries() const
. Последний случай работает нормально.
Как можно объяснить это поведение?
Объект, возвращающийся из get_entries(), создает итератор и затем уничтожается. Впоследствии вы пытаетесь разыменовать итератор на уничтоженном контейнере и сбой. Это происходит потому, что объекты, которые возвращаются по значению и не хранятся в любом месте, имеют очень короткий срок службы. – Shloim
Тот же вопрос, что и этот: http://stackoverflow.com/questions/30041907/can-i-use-nested-loops-with-vectors-in-cpp – PaulMcKenzie