关于cocos2d-x内存管理的一个疑惑

Hi all

今天在调试cocos2d-x的代码的时候发现一个问题,请大家帮忙看一下
我的开发环境是WIN7,VC2010
cocos版本
cocos2d-2.1beta3-x-2.1.0 @ Dec 05 2012
cocos2d-2.0-x-2.0.4 @ Nov 02 2012

我先贴一小段代码,代码很简单BattleFiledScene是一个继承CCScene的子类,在它的构造中创建了一个CCLayer,然后添加到scene中,再在析构的时候delete这个CCLayer。运行程序,再点X退出,出弹出一个内存释放遇到野指针的错误。

感觉这是因为在调用addChild函数的时候,它把我的对象加入了对象管理池?这样在关闭程序的时候被删除了2次
但是我追踪了addChild的代码,只看到里面把testLayer加入到了scene的child数组而已,没看到有添加到对象
管理池。

BattleFiledScene::BattleFiledScene()
{
testLayer = new CCLayer();
//backgroundLayer->autorelease();
this->addChild(testLayer); //这行注释掉则不会出现这个问题
}
BattleFiledScene::~BattleFiledScene()
{
delete testLayer;
}

同时还有一种情况,按照上面的方式,我在一个CCLayer中,也这样添加一个CCSprite,运行程序,再退出则不会出现错误。
addChild是CCNode中的函数,CCLayer和CCScene在addchild的时候应该是执行一样的代码,为何会出现这种差异呢?

BackgroundLayer::BackgroundLayer()
{
danDingCardSprite = new DanDingCard();
danDingCardSprite->setPosition(ccp(0,0));
this->addChild(danDingCardSprite);
}
BackgroundLayer::~BackgroundLayer()
{
delete danDingCardSprite;
}
但是我在CCLayer中new出一个Sprite,然后把sprite添加到Layer中,再在析构函数中delete这个sprite。运行
再退出游戏,则不会出现异常。

调试了一下源码,scene并没有直接把子对象添加到对象管理池中去,但是在addchild的时候,会对保存子对象的array进行realloc,在重新分配后会把这个array加入到对象管理池中去了,这样也就相当于把array中的子对象也都加入到对象管理池中去了吧

你layer到scene那个:你析构函数里的调用delete后( 已被释放),但你的scene会调用父类CCNode的析构函数,CCNode会释放他所有的子节点,包括你的layer,但他已被你delete了,所以肯定是野指针。你的内存管理方式是有问题的。还有你直接使用new出来的layer对象是不行的,cocosd-x遵循两段构造,你没有调用一些init方法,对象是不完整的 ~~~~~
至于下面为什么,那就不好说了,那只是你认为一样,事实上另说了
~{:soso_e113:}

如果从尽量使用cocos2d-x本身的内存管理机制上, 你这个写法可能不是太好.

最好使用cclayer::create()这样的模式来创建新的对象. 不要自己手动管理内存.

你layer到scene那个:你析构函数里的调用delete后( 已被释放),但你的scene会调用父类CCNode的析构函数,CCNode会释放他所有的子节点,包括你的layer,但他已被你delete了,所以肯定是野指针。你的内存管理方式是有问题的。还有你直接使用new出来的layer对象是不行的,cocosd-x遵循两段构造,你没有调用一些init方法,对象是不完整的 ~~~~~
至于下面为什么,那就不好说了,那只是你认为一样,事实上另说了
~{:soso_e113:}

如果从尽量使用cocos2d-x本身的内存管理机制上, 你这个写法可能不是太好.

最好使用cclayer::create()这样的模式来创建新的对象. 不要自己手动管理内存.