Box2D crash in b2BlockAllocator.cpp

Box2D crash in b2BlockAllocator.cpp

本文关键字:cpp b2BlockAllocator in crash Box2D      更新时间:2023-10-16

我最近刚开始使用Box2D与C++和Visual Studio 2015,并且遇到了一个非常奇怪的错误,其中我在第155行收到由b2BlockAllocator引起的访问冲突.cpp。 似乎一个数组被分配给某种 b2Block 链表结构,其下一个值为 null。 这就是触发访问冲突的原因。

if (m_freeLists[index])
{
    b2Block* block = m_freeLists[index];
    m_freeLists[index] = block->next; // <- error occurs here.
    return block;
}
else
{...

但奇怪的是。我一直在开发一个供个人使用的游戏库,以下代码用于在游戏库中的 PhysicsObject 类中实例化 b2Body:

void PhysicsObject::onCreate()
{
    /**/
    b2BodyDef bodyDef;
    bodyDef.type = m_bodyType;
    bodyDef.position.Set((float)(m_x + m_width / 2) / (float)m_pLevel->getTileSize(), (float)(m_y + m_height / 2) / (float)m_pLevel->getTileSize());
    m_pBody = m_pLevel->getWorld().CreateBody(&bodyDef);
    b2PolygonShape shape;
    shape.SetAsBox((float)m_width / (float)m_pLevel->getTileSize() * 0.5f, (float)m_height / (float)m_pLevel->getTileSize() * 0.5f);
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &shape;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.3f;
    m_pBody->CreateFixture(&fixtureDef); // <- This call is the last executed before the error.
    /**/
}

这是在游戏库中,这是一个Visual Studio DLL项目,它工作得很好。但是,当我将此 EXACT 代码移动到引用游戏库的测试项目中派生自 PhysicsObject 的类时,会发生崩溃。将每个对象分配到堆也不会有什么区别,因为 Box2D 文档指出,它们传递到的对象不保留引用。如果这有帮助,Box2D 是一个静态链接的库。测试项目和游戏库具有完全相同的依赖项,并且处于相同的配置中。有没有人知道为什么会发生这种情况?任何帮助非常感谢。

更新:

我已经发现了导致崩溃的原因,但我不确定如何修复它。问题是Box2D的区块分配器在世界创建b2Body之后以某种方式变得腐败。这是分配前的免费块列表的样子:

分配前

创建 b2Body 后:

分配后

如您所见,块列表中显然存在损坏的内存。有谁知道为什么会这样? 静态链接我的项目可以解决这个问题吗?

我遇到的问题与从 DLL 中的代码传输到可执行文件中的代码之间发生的内存损坏有关。虽然我不确定为什么会这样,但我认为这可能与DLL Hell有关。解决方案是使我的游戏库成为静态库而不是动态库。这只是将所有代码直接编译到可执行文件中,并且不会发生由转换引起的内存损坏。

我在创建 b2BodyDeF 时错误地设置了用户数据。我认为用户数据导致内存问题,当 b2Body 被破坏时出现问题。正确设置用户数据后,问题已解决。

我的游戏在 BlockAllocator 中没有崩溃,但它在 b2Contact::D estroy() 中崩溃了。发生在我身上的是:

  1. 我叫b2World::Step()
  2. 让一个 b2ContactListener 派生的类侦听游戏逻辑的冲突。 b2ContactListener::BeginContact() 被调用
  3. b2ContactListener::BeginContact() 在别的地方调用了一个函数 f()。
  4. f() 进行了一次调用,使 b2World 重新更新。
  5. b2World 删除了一些 b2Contacts,它们仍然在堆栈上 2)
  6. 当逻辑完成后,我在 2 处被带回 BeginContact()。然后 BeginContact() 访问已删除的对象,从而导致崩溃。

我希望这对崩溃故障排除有所帮助。我的Visual Studio调试器也显示不可读的内存,所以它让我感到困惑。我以为这是Box2D的错误,但是...哈。错误被制造 b