Memory leak in replaceScene with CCTransitionFade ?

I am getting a memory leak when replacing scenes and using CCTransitionFade.
This at least according to Visual Leak Detector (which I’m not that familiar with)

Am able to reproduce this, in a simple Hello World example, plus one additional CCScene to switch to.
Using shared director to replace scene:

CODE:

    // Initiate transition to Exit scene
    CCScene* exitScene = ExitScene::scene();
    CCDirector::sharedDirector()->replaceScene(CCTransitionCrossFade::create(1.0f, exitScene ));

This does NOT happen when replacing scene without transition:

    CCDirector::sharedDirector()->replaceScene(exitScene);

I am using latest cocos2d-x version (Cocos2d-2.0-x-2.0.3).

Can someone confirm this ?
Or am I using replaceScene method incorrectly ?
Or perhaps a case of Visual Leak Detector false alarm ?

Cheers !

Visual Leak Detector log:

WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x00B1EE88: 416 bytes ----------
  Call Stack:
    c:\users\lmendesx\git\samecolor_cocos2dx_new\samecolor\classes\scenes\splashscene.h (19): Samecolor.win32.exe!SplashScene::create + 0x47 bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\samecolor\classes\scenes\splashscene.cpp (13): Samecolor.win32.exe!SplashScene::scene + 0x5 bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\samecolor\classes\appdelegate.cpp (36): Samecolor.win32.exe!AppDelegate::applicationDidFinishLaunching + 0x5 bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\cocos2dx\platform\win32\ccapplication.cpp (47): libcocos2d.dll!cocos2d::CCApplication::run + 0xF bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\samecolor\proj.win32\main.cpp (30): Samecolor.win32.exe!wWinMain + 0x19 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (547): Samecolor.win32.exe!__tmainCRTStartup + 0x2C bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): Samecolor.win32.exe!wWinMainCRTStartup
    0x751F339A (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes
    0x77579EF2 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes
    0x77579EC5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes
  Data:
    5C BC 20 01    57 02 00 00    00 00 00 00    01 00 00 00     \...W... ........
    00 CD CD CD    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 80 3F    00 00 80 3F    88 2D AB 0F    58 02 00 00     ...?...? .-..X...
    00 00 00 00    01 00 00 00    00 CD CD CD    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    48 F6 B1 00     ........ ....H...
    00 00 00 00    00 00 00 00    01 CD CD CD    88 2D AB 0F     ........ .....-..
    59 02 00 00    00 00 00 00    01 00 00 00    00 CD CD CD     Y....... ........
    00 00 00 3F    00 00 00 3F    88 2D AB 0F    5A 02 00 00     ...?...? .-..Z...
    00 00 00 00    01 00 00 00    00 CD CD CD    00 00 70 43     ........ ......pC
    00 00 C8 43    9C 2D AB 0F    5B 02 00 00    00 00 00 00     ...C.-.. [.......
    01 00 00 00    00 CD CD CD    00 00 F0 43    00 00 48 44     ........ ...C..HD
    00 CD CD CD    F8 DB B1 00    01 CD CD CD    FF FF FF FF     ........ ........
    00 00 00 00    00 00 00 00    D8 B0 B1 00    00 00 00 00     ........ ........
    08 00 00 00    48 9E B1 00    D0 9D B1 00    00 00 80 3F     ....H... .......?
    00 00 00 00    00 00 00 80    00 00 80 3F    00 00 00 00     ........ ...?....
    00 00 00 00    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........


---------- Block 2 at 0x067D06B8: 416 bytes ----------
  Call Stack:
    c:\users\lmendesx\git\samecolor_cocos2dx_new\samecolor\classes\scenes\exitscene.h (47): Samecolor.win32.exe!ExitScene::create + 0x47 bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\samecolor\classes\scenes\exitscene.h (37): Samecolor.win32.exe!ExitScene::scene + 0x5 bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\samecolor\classes\scenes\splashscene.cpp (59): Samecolor.win32.exe!SplashScene::ccTouchesBegan + 0x5 bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\cocos2dx\touch_dispatcher\cctouchdispatcher.cpp (419): libcocos2d.dll!cocos2d::CCTouchDispatcher::touches + 0x2E bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\cocos2dx\touch_dispatcher\cctouchdispatcher.cpp (493): libcocos2d.dll!cocos2d::CCTouchDispatcher::touchesBegan
    c:\users\lmendesx\git\samecolor_cocos2dx_new\cocos2dx\platform\cceglviewprotocol.cpp (224): libcocos2d.dll!cocos2d::CCEGLViewProtocol::handleTouchesBegin + 0x1A bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\cocos2dx\platform\win32\cceglview.cpp (243): libcocos2d.dll!cocos2d::CCEGLView::WindowProc + 0x20 bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\cocos2dx\platform\win32\cceglview.cpp (78): libcocos2d.dll!cocos2d::_WindowProc + 0x20 bytes
    0x74F562FA (File and line number not available): USER32.dll!gapfnScSendMessage + 0x332 bytes
    0x74F56D3A (File and line number not available): USER32.dll!GetThreadDesktop + 0xD7 bytes
    0x74F60D27 (File and line number not available): USER32.dll!GetClientRect + 0xC5 bytes
    0x74F60D4D (File and line number not available): USER32.dll!CallWindowProcW + 0x1B bytes
    0x18F560FB (File and line number not available): OPENGL32.dll!wglSwapBuffers + 0x2DA bytes
    0x74F562FA (File and line number not available): USER32.dll!gapfnScSendMessage + 0x332 bytes
    0x74F56D3A (File and line number not available): USER32.dll!GetThreadDesktop + 0xD7 bytes
    0x74F577C4 (File and line number not available): USER32.dll!CharPrevW + 0x138 bytes
    0x74F5788A (File and line number not available): USER32.dll!DispatchMessageW + 0xF bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\cocos2dx\platform\win32\ccapplication.cpp (86): libcocos2d.dll!cocos2d::CCApplication::run + 0xC bytes
    c:\users\lmendesx\git\samecolor_cocos2dx_new\samecolor\proj.win32\main.cpp (30): Samecolor.win32.exe!wWinMain + 0x19 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (547): Samecolor.win32.exe!__tmainCRTStartup + 0x2C bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): Samecolor.win32.exe!wWinMainCRTStartup
    0x751F339A (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes
    0x77579EF2 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes
    0x77579EC5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes
  Data:
    5C BE 20 01    DE 03 00 00    00 00 00 00    01 00 00 00     \....... ........
    00 CD CD CD    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 80 3F    00 00 80 3F    88 2D AB 0F    DF 03 00 00     ...?...? .-......
    00 00 00 00    01 00 00 00    00 CD CD CD    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    01 CD CD CD    88 2D AB 0F     ........ .....-..
    E0 03 00 00    00 00 00 00    01 00 00 00    00 CD CD CD     ........ ........
    00 00 00 3F    00 00 00 3F    88 2D AB 0F    E1 03 00 00     ...?...? .-......
    00 00 00 00    01 00 00 00    00 CD CD CD    00 00 70 43     ........ ......pC
    00 00 C8 43    9C 2D AB 0F    E2 03 00 00    00 00 00 00     ...C.-.. ........
    01 00 00 00    00 CD CD CD    00 00 F0 43    00 00 48 44     ........ ...C..HD
    01 CD CD CD    60 05 7D 06    01 CD CD CD    FF FF FF FF     ....`.}. ........
    00 00 00 00    00 00 00 00    D8 B0 B1 00    00 00 00 00     ........ ........
    08 00 00 00    48 9E B1 00    D0 9D B1 00    00 00 80 3F     ....H... .......?
    00 00 00 00    00 00 00 80    00 00 80 3F    00 00 00 00     ........ ...?....
    00 00 00 00    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........


Visual Leak Detector detected 2 memory leaks (904 bytes).
Largest number used: 904 bytes.
Total allocations: 904 bytes.
Visual Leak Detector is now exiting.
cocos2d: deallocing 0FB2BF00

Hi

The code you wrote is correct.
I guess you forgot some memory release in destructor.

Luis Mendes wrote:

I am getting a memory leak when replacing scenes and using CCTransitionFade.
This at least according to Visual Leak Detector (which I’m not that familiar with)
>
Am able to reproduce this, in a simple Hello World example, plus one additional CCScene to switch to.
Using shared director to replace scene:
>
CODE:
>
[…]
>
This does NOT happen when replacing scene without transition:
>
[…]
>
I am using latest cocos2d-x version (Cocos2d-2.0-x-2.0.3).
>
Can someone confirm this ?
Or am I using replaceScene method incorrectly ?
Or perhaps a case of Visual Leak Detector false alarm ?
>
>
Cheers !
>
Visual Leak Detector log:
>
[…]

I ran TestCpp with memory leak test, but not found any memory leak.

I did it like this:

  1. open TestCpp/proj.ios/TestCpp.xcodeproj
  2. the target is set to iPhone 6.0 Simulator
  3. select Product~~>Profile~~>Memory Leaks
  4. run TransitionsTest

Hum… I quickly retested from a clean start. Unpack latest cocos2d-x release add other scene and logic to change scene to HelloCpp project.
No memory leaks detected this time :slight_smile: Now I have to figure out where does it occur in my code.

Still not figured out what is causing the memory leak.
At least I’m not creating new instances of objects, only using CCNode based ones.

But isn’t so that, if one uses CCNode based objects, and creates them using the available static methods, and leaves them as auto-release the memory management should be done automatically ?

Yes, the static methods create an autorelease objects, so there’s no need to release them.
Try commenting out lines teal you’ll find the one that is causing the leak.

Still don’t understand where memory is leaking in the following case, I’m not a skilled C++ developer though :slight_smile:

If someone is willing to reproduce it, it’s fairly easy:

  1. Add the following header named ExitScene.h to HelloCpp project at samples\HelloCpp\Classes

    #ifndef EXIT_SCENE_H
    #define EXIT_SCENE_H

    #include “cocos2d.h”

    USING_NS_CC;

    class ExitScene : public CCLayerColor
    {
    public:

     static CCScene* scene()
     {
         // Create scene
         CCScene * scene = CCScene::create();
         if(!scene) return NULL;
    
         // Create layer
         ExitScene *layer = ExitScene::create();
         if(!layer) return NULL;
    
         // Add layer to scene
         scene->addChild(layer);
    
         // return the scene
         return scene;
     }
    
     // implement the "static node()" method manually
     CREATE_FUNC(ExitScene);
    
     // init
     virtual bool init()
     {
         // Super init
         if(! CCLayerColor::initWithColor( ccc4(0, 0, 0, 255) )) return false;
    
         // schedule exit
         schedule(schedule_selector(ExitScene::exitGame), 0.5f);
    
         return true;
     }
    
     // exit
     void exitGame(float ct)
     {
         // End application
         CCDirector::sharedDirector()->end();
     }
    

    };

    #endif // EXIT_SCENE_H

  1. Include header in HelloWorldScene.cpp

    #include “ExitScene.h”

  2. Modify HelloWorld::menuCloseCallback method to make a scene transition.

     //CCDirector::sharedDirector()->end();
     CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(1.0f, ExitScene::scene()));
    

This execution gives me 2 memory leaks.
At least using Virtual Leak Detector, dunno what’s the best tool for this.

However if ditching the transition, like bellow, I have no memory leaks.

    //CCDirector::sharedDirector()->end();
    CCDirector::sharedDirector()->replaceScene(ExitScene::scene());

Tried these things so far in attempt to figure out the memory leak.

  1. Changed to scheduleOnce in init() method from ExitScene.
  2. removed schedule, and called exitGame() directly from init() method from ExitScene.
  3. manually implemented CREATE_FUNC macro, and removed autorelease(), released it manually in onExit() method from ExitScene.

Always get 2 memory leaks originated in the layer create method:

* exitscene.h (30): HelloCpp.exe!ExitScene::create + 0x47 bytes
* helloworldscene.h (31): HelloCpp.exe!HelloWorld::create + 0x47 bytes

If there’s no apparent error in the code above, then we might have a problem in cocos2d-x or Virtual Leak Detector (probably in the last one)

Anyone good wiling enough to quickly validate the code in comment #7 ?
Considering the autorelease logic, I cannot determine where the memory leak is originated…
In spite of the reason being very likely something obvious :slight_smile:

Hi

I tried your code and the transition doesn’t work - it just jumps with no fade.

I also got the following message when using CCTransitionFade in your code:-

“cocos2d-x debug info cocos2d: removeChildByTag: child not found!”

Don’t know if this helps.

David Greenberg wrote:

Hi
>
I tried your code and the transition doesn’t work - it just jumps with no fade.
>
I also got the following message when using CCTransitionFade in your code:-
>
“cocos2d-x debug info cocos2d: removeChildByTag: child not found!”
>
Don’t know if this helps.

Hi David,

I might have missed something.
Here’s the HelloWorld sources example attached in a zip file if you wanna try it.

Note) I’m using cocos2d-2.0-x-2.0.3 as base. Also if you’re not using Virtual Leak Detector, please remove/comment out the following line from AppDelegate.h.

#include 

And thanks for helping :slight_smile:

Hi Luis

I’m not using Visual C++ so I can’t test Virtual Leak Detector.

I did notice that when I changed from CCLayerColor to CCLayer the fade worked.

Again, I don’t know if this helps.

I don’t use CCTransitions myself.

I tend to do my own fades by changing the alpha of a blank sprite, just because that’s how I’ve done it for years on other platforms.

Sorry I couldn’t be of more help.

David

Hi Luis

Please ignore everything I’ve said.

I made a stupid mistake that caused the problems I descibed - your code looks fine.

I think you may be right - it may very well be a problem with Visual Leak Detector.

Apologies if I’ve sent you off on the wrong direction.

David

David Greenberg wrote:

Hi Luis
>
Please ignore everything I’ve said.
>
I made a stupid mistake that caused the problems I descibed - your code looks fine.
>
I think you may be right - it may very well be a problem with Visual Leak Detector.
>
Apologies if I’ve sent you off on the wrong direction.
>
David

Hi David,

No problem, thanks for helping out :slight_smile:
I guess probably it is just VLD related.
But just in case, when I have some time, I’ll try with Linux/valgrind approach.

  • Luís

Yep, seems like VLD gives false positive in new allocations in static objects.

Well, VLD can be disabled/enabled at run-time.
So one can always “wrap” allocation with VLDDisable and VLDEnable methods.

static Foo* create()
{
    // TODO: Workaround for VLD false positives
    VLDDisable();
    Foo *pOb = new Foo();
    VLDEnable();
}