He encontrado un comportamiento muy extraño (en clang y GCC) en la siguiente situación. Tengo un vector, nodescon un elemento, una instancia de clase Node. Luego llamo a una función nodes[0]que agrega un nuevo Nodeal vector. Cuando se agrega el nuevo nodo, los campos del objeto que llama se restablecen. Sin embargo, parecen volver a la normalidad una vez que la función ha finalizado.
Creo que este es un ejemplo reproducible mínimo:
#include <iostream>
#include <vector>
using namespace std;
struct Node;
vector<Node> nodes;
struct Node{
    int X;
    void set(){
        X = 3;
        cout << "Before, X = " << X << endl;
        nodes.push_back(Node());
        cout << "After, X = " << X << endl;
    }
};
int main() {
    nodes = vector<Node>();
    nodes.push_back(Node());
    nodes[0].set();
    cout << "Finally, X = " << nodes[0].X << endl;
}
Que salidas
Before, X = 3
After, X = 0
Finally, X = 3
Aunque esperarías que X permanezca sin cambios por el proceso.
Otras cosas que he probado:
- Si elimino la línea que agrega un 
Nodeinteriorset(), genera X = 3 cada vez. - Si creo un nuevo 
Nodey lo llamo en ese (Node p = nodes[0]), la salida es 3, 3, 3 - Si creo una referencia 
Nodey la llamo en ese (Node &p = nodes[0]), entonces la salida es 3, 0, 0 (¿quizás esta es porque la referencia se pierde cuando el vector cambia de tamaño?) 
¿Es este comportamiento indefinido por alguna razón? ¿Por qué?

reserve(2)al vector antes de llamarlo,set()este sería un comportamiento definido. Pero escribir una función comosetesa requiere que el usuarioreservetenga el tamaño adecuado antes de llamarla para evitar un comportamiento indefinido, es un mal diseño, así que no lo haga.Respuestas:
Su código tiene un comportamiento indefinido. En
El acceso a
Xes realmentethis->Xythises un puntero al miembro del vector. Cuando lo hacenodes.push_back(Node());, agrega un nuevo elemento al vector y ese proceso se reasigna, lo que invalida todos los iteradores, punteros y referencias a elementos en el vector. Eso significaestá utilizando un
thisque ya no es válido.fuente
push_backcomportamiento ya indefinido (ya que estamos en una función miembro con invalidadothis) o UB ocurre la primera vez que usamos elthispuntero? ¿Sería posible es decirreturn 42;?nodeses independiente de unaNodeinstancia, por lo que no hay UB en las llamadaspush_back. El UB está usando el puntero inválido después.void set(Node* this), no está indefinido pasarle un puntero no válido ofree()en la función. No estoy seguro, pero imagino que incluso((Node*) nullptr)->set()se define si no se usathisy el método no es virtual.((Node *) nullptr)->set()esté bien, ya que esto hace referencia a un puntero nulo (se ve claramente cuando se escribe de manera equivalente como(*((Node *) nullptr)).set();).reasignará el vector, cambiando así la dirección de
nodes[0], perothisno se actualiza.intente reemplazar el
setmétodo con este código:observe cómo
&nodes[0]es diferente después de llamarpush_back.-fsanitize=addresscaptará esto e incluso le dirá en qué línea se liberó la memoria si también compila-g.fuente