原文链接:http://blog.csdn.net/zhangxaochen/article/details/8033270
box2d 内存管理: b2Shape 的管理
写box2d 的代码,往往都见过这样的一段:
b2EdgeShape groundEdge; b2FixtureDef boxShapeDef; boxShapeDef.shape=&groundEdge;
这个代码往往写在 init() 之类的函数里,创建四条边,用来框定屏幕区域。
刚见到这段代码的时候我很疑惑的一点是, groundEdge 作为创建在栈内存上的变量,在超出函数体——例如刚刚提到的init() 时候就被析构销毁了。可是,我们却把他的地址赋给了 boxShapeDef.shape 域:
boxShapeDef.shape=&groundEdge;
那么真正运行起来的时候, 循环主体肯定是在 init() 之外的,程序为什么没有因为 shape域指针指向无效地址而 crash呢?
实际情况是这样的:
Box2D 自己管理 b2Shape 的拷贝。一般接着上面的代码会有这样的代码:
groundBody->CreateFixture(&boxShapeDef);
关键就在这里,CreateFixture 做了什么?他怎么使用的 boxShapeDef 呢?
调试跟进发现,在 b2Body.cpp 163行:
fixture->Create(allocator, this, def);
参数里有个“def”实参,就是 上面传进来的 &boxShapeDef。继续跟入,在 b2Fixture.cpp 的
void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def)
函数内,有一句:
m_shape = def->shape->Clone(allocator);
Box2D 最终根本没有用一开始我们创建的栈上的局部变量! 他制作了shape的一份拷贝,赋值给 m_shape 成员变量,之后即便 我们的groundEdge 被销毁了,Box2D 仍然持有有效的数据,而不是无效指针。。。
疑惑解除了~
原文链接:http://blog.csdn.net/zhangxaochen/article/details/8033270
{{OVER}}