ofRegisterTouchEvents - not working if the object is in a vector

Greetings OF Universe!

I have a simple button class that calls ofRegisterTouchEvents(this) in setup. It works great when I create a single instance. When I create multiple instances in a loop and store them in a vector it no longer works. If I use a shared pointer in the vector they work as expected.

This works
coolButton button;

These don’t receive touch events
vector<coolButton> buttons;

But these do
vector<shared_ptr<coolButton>> betterButtons;

In the mm file

for (int i = 0; i < NUM_BUTTONS; i++) {
    // don't receive touch events  
     coolButton button;
     buttons.push_back(button);
     buttons[i].setup(i);   

    // these work as expected
    betterButtons.push_back(shared_ptr<ixWordButton>(new ixWordButton()));
    betterButtons[i]->setup(i);

}

Can someone explain why it works this way?

OF 0.9.0 iOS

This is a problem with callbacs to objects in c++. vectors move memory around when you push_back to them so when you set up the object, ofEvent stores a pointer to it but when that object is moved by the vector to a different location the ofEvent pointer becomes invalid and your application should even crash. There’s no easy way to solve this except for having some kind of event where objects can poll from instead of receive callbacks.

A possible solution is also to preallocate the vector so it doesn’t reallocate the objects and then call setup on them like:

buttons.resize(NUM_BUTTONS);
for(auto & button){
    button.setup()
}

that way buttons never move from their original location and the addresses are always valid. another solution if you need to dynamically allocate new buttons (or remove them) after the app has started is to use a list instead of a vector which never moves the objects from their original locations

Ahh. This makes sense.

Preallocating the vector also works.

Thanks @arturo!