std::vector problem after clearing

Started by
2 comments, last by Zahlman 15 years, 4 months ago
I'm trying to implement a blockmap to do collision detection for particles using stl vectors. I've set up an array of std::vectors and then add the pointers to the particles that appear in that array location to the vector there. After I build the map, then I'll go through and compute any collisions. But after it goes through once, then it crashes. I've narrowed it down to the way I'm clearing out the vectors after each pass. But I don't know how to handle the vectors correctly. I want to be able to clear out the vectors in each array location, but I'm doing it wrong. Edit: I should add that the crash happens in the fill blockmap section after I move to a new location. If I keep adding particles to the original location, it works just fine. It's only when I add particles to a new location that every goes to hell Here's the code I've written:

//make the blockmap
std::vector<Particle*> blockmap[BLOCK_MAP_SIDE_SIZE * BLOCK_MAP_SIDE_SIZE];

//fill blockmap
if(sparks.size() > 1)
{
	for(std::vector<Particle>::iterator iter = sparks.begin(); iter != sparks.end(); iter++)
	{
		blockmap[iter->Get_BlockPos()].push_back(iter->Get_Pointer());
	}
}

//compute collisions
for(int i = 0; i < BLOCK_MAP_SIDE_SIZE * BLOCK_MAP_SIDE_SIZE; i++)
{
	if (blockmap.size() > 1)
	{
		for(std::vector<Particle*>::iterator iter = blockmap.begin(); iter != blockmap.end(); iter++)
		{
			//do collisiony stuff here
		}
	}
	blockmap.clear();
}


Any ideas what I'm doing wrong?
Advertisement
For starters, why are you mixing vectors and arrays? Just use one or another:

std::vector<std::vector<Particle*> > blockmap(BLOCK_MAP_SIDE_SIZE * BLOCK_MAP_SIDE_SIZE);

My guess is that you're trashing memory somewhere, but without seeing any more code or knowing exactly which line causes the crash (or what the crash even says), it's hard to tell. Start with the above change, and see if perhaps you're going out-of-bounds somewhere.
Ah, thanks Zipster. That wasn't it, but the line that I might be trashing my memory got me searching in the right direction. It ended up that I was computing my position into the blockmap wrong. I'm using an 8*8 blockmap, and I was ending up with values in the 300's. Once I fixed that, all my problems went away.

Thanks Zipster,

- Goishin
If your "collisiony stuff" doesn't explicitly require building lists of particles in the same cell (is it to do more detailed collision checks? If so, have you accounted for the possibility that two particles collide near a cell border?), you can do it a lot more simply. Even then, maybe this gives you some ideas for code cleanup:

Particle dummy;Particle* blockmap[BLOCK_MAP_SIDE_SIZE * BLOCK_MAP_SIDE_SIZE];// The if-check here was near useless; you're optimizing the unusual case.// Consider also that it's perfectly OK to iterate over an empty container.for (std::vector<Particle>::iterator iter = sparks.begin(); iter != sparks.end(); ++iter) {	Particle*& current = blockmap[iter->Get_BlockPos()];	if (!current) { current = &*iter; }	// you don't need a member function to get a pointer	else {		iter->collided();		if (current != &dummy) { current->collided(); current = &dummy; }	}}// BTW, standard library containers don't need to be explicitly .clear()ed at// the end; this happens automatically in their destructors.

This topic is closed to new replies.

Advertisement