Segmentation fault in iterator dereferencing

不羁的心 提交于 2019-12-12 04:14:57

问题


The code listed below triggers a segmentation fault in the iterator based loop:

#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;
    }   
}

On the other hand, the index based loop works ok.

This behaviour is triggered when a copy of the std::vector is returned (see: const std::vector<A*> get_entries() const) and not a const reference to it, as e.g. const std::vector<A*>& get_entries() const. The latter case works fine.

How could this behaviour be explained?


回答1:


Since get_entries() returns a vector by value, you're using a different std::vector<A*> object every time. Comparing iterators from different vectors is Undefined Behavior, so even with just get_entries().begin() != get_entries().end() you're already in trouble.




回答2:


The problem is that get_entries returns a temporary copy of the vector, not a reference to the original. So every time you are calling it and grabbing the iterator to a temporary return value, that iterator will be invalid by the time you come to use it. That leads to undefined behaviour, in which a crash is pretty common.

You have two options here.

Option 1: Store the returned vector in a local variable and iterate over that.

Option 2: Modify the function to return a reference const std::vector<A*> & get_entries() const.



来源:https://stackoverflow.com/questions/34008337/segmentation-fault-in-iterator-dereferencing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!