C++/STL Deque Problem with Insert Method...

Started by
4 comments, last by silvermace 19 years, 6 months ago
Before I start... Visual C++ .NET 2003 is my compiler and os Windows XP. ----------------- This seems like a freak accident, I'm not really sure what it's happenning. Basically I'm writing a block of code that will go through an image with RGBA values, get 32 shades of each color, and then find the most popular colors. Basically I setup a vector that stores a count of all of the different colors in the image, there's nothing that I can find wrong here. It seems to do everything A-OK. Here's the code for reference though (my realy code problems are the next block).

vector<unsigned int*> pColors;
deque<unsigned int*> p256Colors;

// Loop through all data converting to 32 shades
for (int i = 0 ; i < width * height * 4 ; i += 4)
{
	bool found = false;
	unsigned long found_index;
    unsigned char        rgb[3];
	unsigned int*		 pTemp = new unsigned int[4];
	unsigned int*		 pCurrent;

	// Grab RGB
    RGBA_To_RGB(data + i, rgb);

	//  32 shades all set everything to
    data		= (unsigned char)(rgb[0]/8);
    data[i+1]	= (unsigned char)(rgb[1]/8);
    data[i+2]	= (unsigned char)(rgb[2]/8);

	// Store color data
	for( int j = 0 ; j < 3 ; j++ ) {
		pTemp[j] = (int)data[i+j];
	}

	// Loop through entire vector looking for current
	for( int j = 0 ; j < (int)pColors.size() ; j++ ) {

		// Get current color
		pCurrent = pColors.at(j);

		// Look for null
		if( pCurrent == NULL ) continue;

        // check to see if color already listed in color table
		if( pCurrent[0] == pTemp[0] && pCurrent[1] == pTemp[1] && pCurrent[2] == pTemp[2] ) {
			found = true;
			found_index = j;
			break;
		}

	}
	
	// If we didn't find the color
	if( !found ) {

		// Set first found
		pTemp[3] = 1;

		// Push onto color table
		pColors.push_back(pTemp);

	} else {

		// Increment number found of that color
		pCurrent = pColors[found_index];
		pCurrent[3] = pCurrent[3]++;

		// Place back into it's position
		pColors[found_index] = pCurrent;

	}

}

Alright, so when it gets to the next part of the code, it gets an run-time error saying: "Unhandled exception at 0x004306d1 in Project 1.exe: 0xC0000005: Access violation reading location 0x000433f1.". It would seem that my iterator would be pointing to past my proper location in memory, which I don't see where that would happen, I haven't done much STL stuff in about two years. When I look at the call stack it says it came from my insert call on the deque that I created of the colors (I placed a big huge comment where that is). The weird thing is it only happens on one of the images I have tried so far (I've tried about 10). It happens when the deque has a size of 256 (and has been 256 for awhile) and it doesn't happen at the end or the beginning of the list of all of the colors.

printf("finding 256 pop colors\n");

// Find the 256 most popular colors
vector<unsigned int*>::iterator p;
int j22 = 0;
for( p = pColors.begin() ; p != pColors.end() ; p++ ) {
	j22++;
	unsigned int* pCurrent;
	pCurrent = *p;

	printf("SIZE: %d\n",p256Colors.size() );

	// Nothing in 256 Colors, add first element
	if( p256Colors.empty() ) {
		p256Colors.push_front( pCurrent );			
		continue;	
	}

	deque<unsigned int*>::iterator p2;
	for (p2 = p256Colors.begin() ; p2 != p256Colors.end() ; p2++ ) {
		unsigned int* p256Current = *p2;

		// All colors in (full) table have more colors than current
		if( p256Colors.size() == 256 && p256Current[3] >= pCurrent[3] && p2 == p256Colors.begin() ) {
			break;
		}
		

		// Check for upper bounds
		if( p256Current[3] >= pCurrent[3] ) {
			
			// Check for too many colors to keep @ 256 colors
			if( p256Colors.size() == 256 ) {
				p256Colors.pop_front();
			}

			printf("%d::%d",pColors.size(), j22);
			// Insert before current element

                        // put in here as check to try to get rid of error, didn't work.
			if( p2 == p256Colors.begin() ) {
				p256Colors.push_front(pCurrent);
			} else {
/**********************
 * error seems to be here 
 *******/
				p256Colors.insert(p2, pCurrent);
			}
			break;
		}

		// Last element so add at end, new winner!
		if( (p2+1) == p256Colors.end() ) {
			p256Colors.push_back(pCurrent);
			break;
		}
	}
}

I go on to do some other stuff and do the memory management stuff too. Any help would be MUCH appreciated I've been racking my brain at this for a few days now. I will be forever indebted.
Advertisement
Sorry, I forgot to tell you I checked pCurrent and it does point to an actual piece(s) of color data which was given to it with the pColors vector. I just commented out the code that check that stuff. So no weird thing there, I've even checked it vs pColors to make sure it wasn't just putting out close to good blah data.

If you guys can help me, you'll seriously make my day guys. Thanks in advance for ANY help at all.
if i was to take a stab in the dark, i'd say its because your completly destroying 'p2'

changing the vector p256Colors (almost always) will invalidate any interators to that container.

ie. when you call p256Colors.push_front() or p256Colors.pop_front() or possibly even p256Colors.insert(), will make your pointer p2 garbage.
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Thanks, that makes sense I'll check it out and get back to you guys on if it solves it.
Silvermace you are entirely amazing. Thanks, I switched the pop_front to after the insert, works flawlessly a perfect populosity alogrithm. Thanks!
Cheers.
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website

This topic is closed to new replies.

Advertisement