C++ 迭代器解引用中的分段错误

C++ 迭代器解引用中的分段错误,c++,vector,reference,iterator,dereference,C++,Vector,Reference,Iterator,Dereference,下面列出的代码在基于迭代器的循环中触发分段错误: #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*&g

下面列出的代码在基于迭代器的循环中触发分段错误:

#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;
    }   
}
#包括
#包括
甲级{
公众:
A(无符号id=0){id_u=id;}
未签名的get_id(){return id_;}
私人:
未签名的id_389;;
};
B类{
公众:
B(){}
B(std::vector entries):entries_(entries){}
const std::vector get_entries()const{
返回条目;
}
私人:
std::向量项;
};
int main(){
std::向量条目;
for(无符号i=0;i<5;i++){
条目。推回(新A(i));
}
B(条目);
//基于索引的访问(ok)
for(无符号i=0;istd::无法获取_id()问题在于
get_entries
返回向量的临时副本,而不是对原始向量的引用。因此,每次调用它并将迭代器获取到临时返回值时,该迭代器在使用它时将无效。这会导致未定义的行为,其中崩溃非常常见

你有两个选择

选项1:将返回的向量存储在局部变量中,并对其进行迭代


选项2:修改函数以返回引用
const std::vector&get_entries()const

问题是
get_entries
返回向量的临时副本,而不是对原始向量的引用。因此,每次调用它并将迭代器捕获到临时返回值时,该迭代器在使用它时将无效。这会导致未定义的行为,其中崩溃是预先定义的很普通

你有两个选择

选项1:将返回的向量存储在局部变量中,并对其进行迭代


选项2:修改函数以返回引用
const std::vector&get_entries()const

因为
get_entries()
按值返回一个向量,您每次都在使用不同的
std::vector
对象。比较不同向量的迭代器是未定义的行为,因此即使只使用
get\u entries().begin()!=get\u entries().end()
您已经遇到麻烦了。

因为
get\u entries()
按值返回一个向量,您每次都在使用不同的
std::vector
对象。比较不同向量的迭代器是未定义的行为,因此即使只使用
get\u entries().begin()!=get\u entries().end()
您已经遇到麻烦了。

从get\u entries()返回的对象创建一个迭代器,然后将其销毁。之后,您尝试在已销毁的容器上取消对迭代器的引用并崩溃。发生这种情况的原因是,按值返回但未存储在任何位置的对象的生命周期非常短。与此相同的问题:从get_entries()返回的对象创建一个迭代器,然后将其销毁。之后,您尝试在已销毁的容器上取消对迭代器的引用并崩溃。发生这种情况的原因是,按值返回且未存储在任何位置的对象的寿命非常短。与此相同的问题: