Calling std::function causes EXC_BAD_ACCESS

Hi,
I wanted to create sort of helper class to make purchases (not the real money purchases, but rather purchasing goods for an in-game currency) and created a method looking like this:

void StoreHelper::buyProduct(int productId, const std::function<void()>& succeded, const std::function<void()>& failed) {

    //dummy code to wait 2 seconds, it'll send a request here
    Director::getInstance()->getRunningScene()->getChildren().at(0)->runAction(Sequence::createWithTwoActions(DelayTime::create(2.0f), CallFunc::create([&, succeded](){

        succeded(); //EXC_BAD_ACCESS

    })));
}

Running an delay-callfunc sequence is just a placeholder, becase it’ll instead send a request to the external server.

I don’t pass the CallFunc in this function, because I find it unnecessary (I need to retain/release), so instead, I simply use std::function. However this causes EXC_BAD_ACCESS crash:

So. instead I’ve tried storing the std::function inside the class to make sure it won’t get released from memory:

void StoreHelper::buyProduct(int productId, const std::function<void()>& succeded, const std::function<void()>& failed) {

    succededCallback = succeded;

    //dummy code to wait 2 seconds, it'll send a request here
    Director::getInstance()->getRunningScene()->getChildren().at(0)->runAction(Sequence::createWithTwoActions(DelayTime::create(2.0f), CallFunc::create([&](){

        succededCallback();

    })));
}

This however works only sometimes and sometimes it crashes with the same error as above.

getRunningScene() should work on the same thread, but I suspected this be an issue, so I’ve figured out how to make this delay without using cocos2d-x actions:

void StoreHelper::buyProduct(int productId, const std::function<void()>& succeded, const std::function<void()>& failed) {

    std::async(std::launch::async, [&, succeded] () {
        std::this_thread::sleep_for( std::chrono::seconds{2});

        succeded();
    });
}

and this code always works! Why? What’s wrong in the first code?

Please try this:

CallFunc::create(succeded)
1 Like

I said I find CallFunc unnecessary in this case, because it works with CallFunc of course. I’d just like to find out why it doesn’t work with std::function.

This code with CallFunc and it doesn’t work?
I think problem in &. Lambda captures parameters by reference, it this case reference to callback which probably is destroyed after we return from buyProduct function.
So, better use CallFunc::create(succeded) or remove & from lambda and pass parameters by copy.