[Cocos2d-x v3.0 alpha] Memory leak when using "runAction"


#1

Sprite* sprite = Sprite::createWithSpriteFrameName(“hello.png”);
Sequence* s1 = Sequence::create(RotateBy::create(0.5f, 45.0f), NULL);
ActionInterval* a1 = RepeatForever::create(s1);
sprite~~>runAction;
// Memory leak occur if I comment this line, means I don’t add the sprite into layer
//this~~>addChild(sprite);

Imagine, if I create a pool with 50 sprites like this, but I’ve just used 30 sprites of them (by adding the sprite to the layer). So that, the 20 sprites remaining will be leak.

Can you help me how to fix it?
Thank you so much!


#2

How do you know that there is a leak?


#3

Cocos2d using ‘reference count’ helping memory management.
line1: sprite_refcount=0
line2: s1_refcount=0
line3: a1_refcount=0, s1_refcount*=1
line4: a1_refcount*=1

Without ‘this->addChild(sprite)’ the sprite_refcount(reference count of ‘sprite’) will always be ZERO, and delete will called by the memory manage unit at the end of current frame.


#4

Hi,
I use VLD tool to detect memory leak. And in this case, it report there’s a leak.
@Zhuo Fu: you’re not correct
line1 : sprite_ref = 1
line2 : s1_ref = 1
line3 : a1_ref = 1, s1_ref = 2
line4 : sprite_ref = 2
Please check the bellow function with target = sprite in line 1
void ActionManager::addAction(Action pAction, Nodetarget, bool paused)
{
….
target~~>retain;
….
}

My hot fix is modify destructor of Director class.
Director::~Director
{
……
CC_SAFE_RELEASE;
// hot fix begin
if
{
_actionManager~~>removeAllActions();
}
// hot fix end
CC_SAFE_RELEASE(_actionManager);
……
}

Regards,
LCD


#5

Yes, your are right, I forgot autorelease() function will add one reference count. But autorelease pool will call deleted function for object which reference count is NOT larger than 1.
Not addChild to other node means the life-time of the temp object is only one frame.

You can try this.

class myLayer : public CCLayer{
public:
CREATE_FUNC(myLayer);
bool init(){CCLog(“init”);return true;}
~myLayer(){CCLog(“~myLayer”);}
};

void init(){
myLayer *layer = myLayer::create();
}

After call init(), at the end of current frame the ‘~myLayer’ will be printed.