Weird behaviour with class fields when adding to a std::vector
Your code has undefined behavior. In
void set(){
X = 3;
cout << "Before, X = " << X << endl;
nodes.push_back(Node());
cout << "After, X = " << X << endl;
}
The access to X
is really this->X
and this
is a pointer to the member of the vector. When you do nodes.push_back(Node());
you add a new element to the vector and that process reallocates, which invalidates all iterators, pointers and references to elements in the vector. That means
cout << "After, X = " << X << endl;
is using a this
that is no longer valid.
nodes.push_back(Node());
will reallocate the vector, thus changing the address of nodes[0]
, but this
is not updated.
try replacing the set
method with this code:
void set(){
X = 3;
cout << "Before, X = " << X << endl;
cout << "Before, this = " << this << endl;
cout << "Before, &nodes[0] = " << &nodes[0] << endl;
nodes.push_back(Node());
cout << "After, X = " << X << endl;
cout << "After, this = " << this << endl;
cout << "After, &nodes[0] = " << &nodes[0] << endl;
}
note how &nodes[0]
is different after calling push_back
.
-fsanitize=address
will catch this, and even tell you on which line the memory was freed if you also compile with -g
.