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.