Reputation: 322
If I add more than 2 items to the std::vector<A*>
in the way shown below, the member's values of the added items change
Here is a Minimal, Complete and Verifiable Example
:
#include <iostream>
#include <vector>
struct B;
struct C
{
float x;
C(float x)
{
this->x = x;
}
};
struct A : public C
{
bool begin;
bool visible;
B* b;
A(float x, B* parent)
: C(x)
{
begin = false;
visible = false;
b = parent;
}
};
struct B
{
A a1;
A a2;
B(float x1, float x2)
: a1(x1, this), a2(x2, this)
{
a1.visible = true;
}
};
int main()
{
std::vector<B> bs;
std::vector<A*> as;
bs.push_back(B(1, 2));
as.push_back(&bs.back().a1);
as.push_back(&bs.back().a2);
bs.push_back(B(2, 3));
as.push_back(&bs.back().a1);
as.push_back(&bs.back().a2);
for(auto& it : as)
{
std::cout << it->begin << std::endl;
}
std::cin.get();
return EXIT_SUCCESS;
}
There's another Problem with the above code(it already got mentioned in the comments by tobi303):
The pointer B* b
from struct A
becomes invalid due to push_back(B(...))
copying the instance of B
, the solution is to use emplace_back
instead
Upvotes: 1
Views: 64
Reputation: 136405
The problem is that when more elements are added to a vector it may resize itself. When this happens all elements are moved to a new location and all existing pointers and references to elements get invalidated.
There are containers that do not invalidate iterators when new elements are added, such as std::list
and boost::stable_vector
.
I.e. boost::stable_vector<Segment>
or std::list<Segment>
instead of std::stable<Segment>
would fix the issue, provided you do not require contiguous storage of Segment
elements.
Upvotes: 4