Problem with Box2D (EXC_BAD_ACCESS) on world->Step [SOLVED]


#1

Hello,

I’m developing my first game using cocos2d-x and Box2D, and im in end of game development. However at this time i have a critical bug: If i fire too much bullets and this bullets shoot 3/ 4 enemies consecutively i’m getting an EXC_BAD_ACESS on world_->Step.

Follow the error i found that the error are end in this code inside void* b2BlockAllocator::Allocate(int32 size):

m_freeLists[index] = block->next;

That is my code for update my game scene:

void GameScene::update(float dt) {
    world_->Step(dt, 8, 3);

    std::vector<b2Body*> toDestroy;

    // Updates all objects positions.
    for (size_t i = 0; i < objects_->count(); i++)
    {
        Object *object = (Object*) objects_->objectAtIndex(i);
        object->update(dt);
        if (!VisibleRect::getVisibleRect().containsPoint(object->getPosition()))
        {
            toDestroy.push_back(object->getBody());
        }
    }

    // Loop through all of the box2d bodies that are currently colliding, that we have
    // gathered with our custom contact listener...
    std::vector<ContactData>::iterator pos;
    for (pos = contact_listener_->_contacts.begin(); pos != contact_listener_->_contacts.end(); ++pos)
    {
        ContactData contact = *pos;

        // Get the box2d bodies for each object
        b2Body *bodyA = contact.fixtureA->GetBody();
        b2Body *bodyB = contact.fixtureB->GetBody();
        if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL)
        {
            Object *objectA = (Object *) bodyA->GetUserData();
            Object *objectB = (Object *) bodyB->GetUserData();

            // Bullet vs Enemy
            if (objectA->getTag() == Object::kPlayerBullet && objectB->getTag() == Object::kEnemy)
            {
                toDestroy.push_back(bodyA);
                toDestroy.push_back(bodyB);
            }
            // Enemy vs Bullet
            else if (objectA->getTag() == Object::kEnemy && objectB->getTag() == Object::kPlayerBullet)
            {
                toDestroy.push_back(bodyB);
                toDestroy.push_back(bodyA);
            }

        }
    }

    // Loop through all of the box2d bodies we wnat to destroy...
    std::vector<b2Body*>::iterator destroyIt;
    for (destroyIt = toDestroy.begin(); destroyIt != toDestroy.end(); ++destroyIt)
    {
        b2Body *body = *destroyIt;
        Object *object = (Object *) body->GetUserData();

        world_->DestroyBody(body);
        this->removeChild(object, true);
        objects_->removeObject(object, true);
    }
}

I’m using this collision detector: http://www.cocos2d-x.org/forums/6/topics/3160

What i’m doing wrong? Anyone can help please?


#2

Probably you are pushing the same body in the toDestroy list more than one time (e.g. when more than one bullet collides with that body during one step). Thus you are trying to destroy that body more than one time.


#3

Thanks! This is the problem! Solved!


#4

Can you share what you did to fix it. My toDestroy has 2 items and I want to destroy them both. Both get destroyed but I am crashing at the same point you were when I call CreateBody. I always crash on index 6

Printing description of this->m_freeLists:
(b2Block *[14]) m_freeLists = {
[0] = 0x0000000000000000
[1] = 0x0000000103edc0c0
[2] = 0x0000000103ed0080
[3] = 0x000000010050c240
[4] = 0x0000000000000000
[5] = 0x000000010426c280
[6] = 0x00000003005083c0
[7] = 0x00000001027a00e0
[8] = 0x0000000000000000
[9] = 0x0000000104270140
[10] = 0x0000000000000000
[11] = 0x0000000000000000
[12] = 0x0000000000000000
[13] = 0x0000000000000000
}

my _world->DestroyBody(body); is only being called twice.