Sign in to follow this  
BiiXteR

Access violation reading location 0x0000000C.

Recommended Posts

I'm having a problem where this error crashes my game : 

Exception thrown at 0x00CFA4C4 in SDL_Game.exe: 0xC0000005: Access violation reading location 0x0000000C.

It appears this Box2D line (in my code) is causing this error : 

body = World::GetWorld()->CreateBody(&bodyDef);

I know that GetWorld returns a valid pointer, so that's not the problem, however the error also leads me to a Box2D source file (b2BlockAllocator.cpp, line 112) : 

if (m_freeLists[index])
{
    b2Block* block = m_freeLists[index];
    m_freeLists[index] = block->next;
    return block;
}

And when checking the values of m_freeLists it tells me : 

Unable to read memory

This is how I created all the Box2D fitures, bodies etc : 

 

bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(x, y);


body = World::GetWorld()->CreateBody(&bodyDef); // <--- Error here :(


shape.SetAsBox(size.x, size.y);


fixtureDef.shape = &shape;
fixtureDef.density = density;
fixtureDef.friction = friction;


body->CreateFixture(&fixtureDef);

I never remove / free any of these variables in my code at all, so that's not whats causing the error)

 

I'm not sure what else to add here since that's And here's what my b2World looks like : 

b2_world = new b2World(gravity);

And the GetWorld function : 

b2World* World::GetWorld()
{
    return b2_world;
}

I'm not sure what else to add, that's pretty much all Box2D code I have except for stepping the world.

 

Share this post


Link to post
Share on other sites
That's definitely a null pointer crash. If you have proven that GetWorld() returns a valid pointer at that point in code (don't just blindly trust that your new b2World object makes it all the way there), the next thing to check is whether something in CreateBody has been inlined and is accessing NULL.

Where is b2_world defined? Did you define it as a global variable in a header or something silly like that? Edited by Nypyren

Share this post


Link to post
Share on other sites

Assuming it happens at the same location every time, if you have any trouble debugging a wrapper is in order.

 

body = World::GetWorld()->CreateBody(&bodyDef);

 

becomes

 

World* world = World::GetWorld();

if(!world) {

  // Big error logging and debugger stopper here

} else {

  body = world->CreateBody(&bodyDef);

}

 

 

As an implementation pattern, for some game designs it can make sense to have special objects that get returned in error cases, and these special objects make all kinds of noisy alerts whenever they're used in non-final releases, but otherwise act as invisible objects or a small white box or something. This type of "failure object" looks and acts like a regular game object in other ways, but make a simple test to determine if you've got the failure object (e.g. isFailureObject()) or the real object. 

 

It is still a sentinel value just like NULL, meaning it is a key value you need to test against, but unlike NULL it should work as a fully functional object if it ever gets created after the game is released.

Share this post


Link to post
Share on other sites

Assuming it happens at the same location every time, if you have any trouble debugging a wrapper is in order.

 
frob's approach is good. I also recommend just learning to read through the disassembled version of the code (alt-8 in visual studio with the standard keybindings). Out in the "real world" you can't rely on being able to modify code to make debugging easier. :)
 
I'd also definitely take the rest of frob's advice to heart. Or even go a stpe further and just remove ever actually having a pointer in the first place. Most pointers in a project are never _supposed_ to be null, so just don't let them be pointers or be null. For instance, your functions and code could change like so:
 
 
// old way
body = World::GetWorld()->CreateBody(&bodyDef);
 
// new way
body = Physics::CreateBody(World::GetWorld(), &bodyDef);

edit ... for reasons I don't fully understand, the editor cut off the second half of my reply. The very short version is to just stop using so many pointers. Use "value types" and references to objects with more reliable lifetimes. Pointers to objects that could be null are just asking for trouble. Edited by SeanMiddleditch

Share this post


Link to post
Share on other sites

Assuming it happens at the same location every time, if you have any trouble debugging a wrapper is in order.

 

body = World::GetWorld()->CreateBody(&bodyDef);

 

becomes

 

World* world = World::GetWorld();

if(!world) {

  // Big error logging and debugger stopper here

} else {

  body = world->CreateBody(&bodyDef);

}

 

 

As an implementation pattern, for some game designs it can make sense to have special objects that get returned in error cases, and these special objects make all kinds of noisy alerts whenever they're used in non-final releases, but otherwise act as invisible objects or a small white box or something. This type of "failure object" looks and acts like a regular game object in other ways, but make a simple test to determine if you've got the failure object (e.g. isFailureObject()) or the real object. 

 

It is still a sentinel value just like NULL, meaning it is a key value you need to test against, but unlike NULL it should work as a fully functional object if it ever gets created after the game is released.

 

I did this, and it does say "World is nullptr".

b2World* world = World::GetWorld();
if (world == nullptr)
{
    std::cout << "World is nullptr" << std::endl;
}

So, I checked my world.cpp file and realized I never actually created the box2d world...lol

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this