先交代下环境吧。个人在做一个游戏的小功能(算是练习吧),用的cocos2d-x引擎,前些天从3.6版本升级到3.7(引擎内部好像有内存管理相关的改动),出现了一个奇怪的bug。
平台是win7 64 + VS 2013 community updater 5。 工程target都是x86 machine
下午再去xcode下搭建一个试试去,看看是不是ide的问题。
就是这个
https://github.com/acros/cocos2dx_qte问题是这样的:
cocos2d-x里有个类叫Scene,我派生了class MainGameScene : public Scene,派生类中成员变量就加了两个RefPtr指针mUiLayer和mGameLayer。(注:RefPtr是cocos2d-x一个轻量级的shared_ptr类似存在)
通过VS的工具输出,确认Scene和MainGameScene的内存布局如下(这里就给出类末尾一段内容):
1> 708 | | _physicsWorld
1> 712 | | _navMesh
1> 716 | | _navMeshDebugCamera
1> | +---
1> 720 | ?$RefPtr@VLayer@cocos2d@@ mGameLayer
1> 724 | ?$RefPtr@VLayer@cocos2d@@ mUiLayer
1> +---
_navMesh和_navMeshDebugCamera是Scene类最后两个成员变量。
720偏移之前都是Scene的,这个表是正确的。
这个工程里面,cocos2d-x引擎部分是导出成一个dll的,然后主项目去加载它,MainGameScene这个类是在我自己的项目里面创建的。然而将一个指向MainGameScene的Scene*类型传到引擎代码中时,对于scene*内存的读取就发生了诡异的变化!
见下图:
可以看到:scene*的地址是0x060BBC88,加上前面计算的720偏移量,0x060BBF58地址应该是mGameLayer的地址,实际这时通过scene*访问到_navMesh变量时,取到的是mGameLayer地址!!!
图中下方窗口还可以看到,我加了个类型转换后再访问,地址就对了····>_<
(*((qte.exe!cocos2d::Scene*)(&(*((qte.exe!MainGameScene*)(scene))))))._navMesh
和&(scene)->_navMesh 取到的地址差 8 ??????
看起来虚表并没有被破坏掉,而且编译器计算类内成员offset时,这个offset怎么会算错,个人完全没头绪啊····(类成员地址不是类地址+offset计算的吗?)
注:scene*指针只在项目dll工程里面访问才会出现这个错误的偏移计算,我之前想过是不是项目配置错了,但问题是,什么东西配置错了会导致这种错误呢?!
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
https://www.v2ex.com/t/208440
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.