Gelunox Gelunox - 15 days ago 6
C++ Question

C++ Unhandled exception: An invalid parameter was passed to a function that considers invalid parameters fatal

I'm doing a group project at school, we're creating a 2d game, and I'm getting an exception I have no idea what to do with.

A side note: all of this is done in debug mode.

We have a physicsengine class that calculates collision and adds vector forces to entities, the code:

void PhysicsEngine::doPhysicsTick()
{
vector<vector<unordered_set<Entity*>>> *grid = this->grid.getGrid();
unordered_set<Entity*>* updatable = new unordered_set<Entity*>();
unordered_set<Entity*>* collidable = new unordered_set<Entity*>();

const int &r = CollisionGrid::C_GRID_RADIUS;

for (int row = 0; row < grid->size(); row++)
for (int col = 0; col < grid->at(row).size(); col++)
{
collidable->clear();

// put all surrounding grid blocks in a entity list to
// check against collision with the current block

int rw(row - r > 0 ? row - r : 0);
int cl(col - r > 0 ? col - r : 0);

for (int rrow = rw; rrow <= row + r && rrow < grid->size(); rrow++)
for (int rcol = cl; rcol <= col + r && rcol < grid->at(rrow).size(); rcol++)
for (Entity *e : grid->at(rrow).at(rcol)) // It crashes here
collidable->insert(e);

for (Entity *e : grid->at(row).at(col))
{
if (e->isFixed())
continue;

e->speed += gravity;

eBounds.reBox(e->location, e->getSize() + e->speed);

for (Entity *c : *collidable)
if (isOverlapping(eBounds, Box(c, c->getSize())) && e != c)
doCollision(e, c);

updatable->insert(e);
}
}


We have a separate collisiongrid class that manages the grid where we store our entities for collision check (so we don't have to check everything with everything)

the collisiongrid and its underlying
vector
are created when the constructor of the physicsengine is called
PhysicsEngine::PhysicsEngine(World *world) : grid(world)
. But for some reason on only the first tick I see the vector grid points to something nonexistant (size being ridiculously large and such) inside of the loop that fills up collidable.

The error it throws is in the title. If I put a catch block around it, it'll just crash someplace else in some c++ library kind of randomly (different file every time)

and for some reason it crashes in our gameloop class' (the one calling tick of physicsengine) destructor if I don't comment the thing I put in there.

Gameloop::~Gameloop()
{
//if( t ) // t = #include <thread>
// delete t;
}


We are not allowed to use any libraries outside of the Win32 API and some default c++ libraries




Edit: I added some pictures (and undid the dynamic allocation of the unordered_sets)

what it should show:

correct grid

what it sometimes shows on the first tick:
(notice how the pointers are the same, first two shot where made during the same run)

enter image description here

what it shows other times on the first tick:

enter image description here

Answer

I'm cringing when I see all those for without indent nor braces.

Does your program handle tasks? Because this may solve your problem in that case (those kind of exceptions never crash the program at the right time!)

If not, then you need to debug the program some more. Like printing rrow, rrcol, grid->size(), grid->at(rrow)->size everytime before the line where it crashes.

But my money is on the concurrency / memory management side of the code. The fact that it crashes in the destructor in the delete part, makes me think maybe you are handling items that were already deleted elsewhere or concurrently handling items without the appropriate measures. And in your screenshot you have a bunch of size=??? which maybe means that your item/instance was deleted and your pointer points to free memory, causing the crash when accessing it in your loop. It's a tough error to solve.

Additionnally, you should be able to access parameters of your exception in the debugger, if you can, maybe you can post all of its contents?