That section of code definitely looks like it could be the source of the problem, but without knowing too much about your custom classes there’s no way for me to know. Rather than trying to send you off on a wild goose chase by me guessing, let me just try and give you some cocos2d-x tips instead:
1. If you subclass a Cocos2d-x object that uses the create pattern, follow the create pattern in your subclass and use it to instantiate instances of your subclass.
It looks like your RemainingLife is some kind of Node subclass. Instead of instantiating it directly with std::make_ref, make a static RemainingLife::create method that looks something like this:
RemainingLife* RemainingLife::create() {
auto life = new (std::nothrow) RemainingLife();
if (life && life->init()) {
life->autorelease();
return life;
}
delete life;
life = nullptr;
return nullptr;
}
2. Lean on Cocos2d-x’s built-in memory management when you can, instead of using things like shared_ptr.
Any class that follows the create pattern in Cocos2d-x is managed for you (provided you follow the proper usage patterns), so there usually isn’t a need to further manage them with things like shared_ptr. Sure, the autorelease stuff is a little strange when comparing it to typical C++ code (although it should be very familiar to Objective-C devs), but it’s not difficult to understand and works well.
- Retain increases the reference count
- Release decreases the reference count
- Autorelease just means the object will be freed at the next time it’s safe to do so (e.g. the start of the next frame)
Using the create pattern, you can rewrite that section of code to something more like this:
// No need for a vector of shared_ptrs, all of the RemainingLife instances
// will be managed by CC2D (see below)
for (auto remainingLife : _remainingLivesPlayer1) {
// Node::removeChild calls release
this->removeChild(remainingLife);
}
_remainingLivesPlayer1.clear();
// now add in the required number of remaining life indicators
for (int i = 0; i < player1Lives; i++) {
// RemainingLife::create() calls autorelease for you, no need to explicitly do it after instantiation
auto newRemainingLife = RemainingLife::create();
newRemainingLife->initWithPositionAndType(inherited::getGridPosition(20.0f + 5.0f * i, 2.0f), kRemainingLifeType1);
// Node::addChild calls retain, there's no need to explicitly call it in this loop
this->addChild(newRemainingLife.get(), GroundPlace::k5Top);
// All you need to do is put the naked pointer in a vector, its memory is being managed by CC2D
_remainingLivesPlayer1.push_back(newRemainingLife);
}
Sorry, I can’t really point you to exactly what’s going wrong with your code but hopefully some of this helps.