2

I have the following code:

#include <iostream>
#include <vector>

struct A;
struct B {
    B(A *a) : a_(a) { id_ = rand(); }

    int id_;
    A *a_;
};

struct A {
    A() { id_ = rand(); }

    int id_;
    std::vector<B> b_list;
};

int main() {

    std::vector<A> a_list;
    //a_list.reserve(4); // Works

    for (int i = 0; i < 4; i++) {
        a_list.push_back(A());
        A *a = &a_list.back();
        a->b_list.push_back(B(a));

        std::cout << a->id_ << " - " << a->b_list.front().a_->id_ << std::endl;
    }
    for(A &a : a_list) {
        std::cout << a.id_ << " - " << a.b_list.front().a_->id_ << std::endl;
    }
}

A vector in object A contains B's. And B contains a pointer back to the parent object A. After the first push_back of A everything is fine. After the second push_back, the first object A is unreadable if accessed through A -> B -> A.

This only happens with the first object, the following seems to be fine. This does not happen if i use "a_list.reserve(4)" before inserting the elements.

Why does the pointer in the first element get corrupted. Should not std::vector be reliable without using reserve?

  • 2
    No. When you create the `B` instances, you point somewhere into the *current* memory buffer of `a_list`. Then you `push_back` to `a_list` again, causing it to need a larger internal buffer, so it reallocates, invalidating your pointers. Don't keep pointers into a `vector` you are still `push_back`ing to. – BoBTFish Feb 27 '17 at 11:22

0 Answers0