Skip to main content
GameDev.net gamedev.net
🔒 Locked

Help tracking down memory leak with vector/list

Started by okonomiyaki May 25, 2006 at 12:08 PM 8 replies 1k views
Original Post
okonomiyaki
okonomiyaki
I'm showing only a couple memory leaks when the program exits. When I set a breakpoint on the allocation number, it's deep down in STL and traces back to the vector class. I know it's a problem with how I'm using it, but I'm not sure what's wrong. Basically I have a vector of a list. This is ok, right? Like this:

	typedef std::list< AXVertexBuffer* > VertexBufferList;
	typedef std::vector< VertexBufferList > Buffer2DArray;
I am creating the buffers by looping through and creating the list, and then attaching the list to the vector like so:

	for(unsigned int i=0; i<=6; i++) {
		VertexBufferList BufferVector;
		for(unsigned int j=0; j<NumBuffers; j++) {
			AXVertexBuffer *Buffer = new AXVertexBuffer;
			/* init stuff*/

			BufferVector.push_back(Buffer);
		}

		_VertexBuffers.push_back(BufferVector);
	}

And I am deleting it like so. I have to do it this way because FreeUploadedVertexData and FreeVertexBuffer pushes the buffer to the front of the list and makes any iterator invalid. I have a feeling my error is in here. I have debugged though and this does go through every node, since every time the node is pushed to the front, back() successfully gets the next one.

	/*	Delete vertex buffers */
	for(unsigned int i=0; i<(unsigned int)_VertexBuffers.size(); i++) {
		/*	We do it this way because FreeUploadedVertexData changes the
			order of the list and would make our iterator invalid */
		for(unsigned int j=0; j<(unsigned int)_VertexBuffers.size(); j++) {
			AXVertexBuffer *Buffer = _VertexBuffers.back();
			UnlockVertexBuffer(Buffer);
			if(Buffer->Owner) Buffer->Owner->FreeUploadedVertexData();
			else FreeVertexBuffer(Buffer);

			SafeDelete(Buffer);
		}
		_VertexBuffers.clear();
	}
	_VertexBuffers.clear();

Can anyone see a problem with this?
ldeej
ldeej
Shouldn't this line:

AXVertexBuffer *Buffer = _VertexBuffers.back();

be:
AXVertexBuffer *Buffer = _VertexBuffers[j];

?

okonomiyaki
okonomiyaki
Quote:
Original post by ldeej
Shouldn't this line:

AXVertexBuffer *Buffer = _VertexBuffers.back();

be:
AXVertexBuffer *Buffer = _VertexBuffers[j];

?


Nope, because you can't randomly access a list. See my note right above that code. The functions FreeUploadedVertexData and FreeVertexBuffer push the buffer to the front of the list, so back() always will retrieve the next buffer. Thanks though.
ldeej
ldeej
Out of curiosity, why are you doing this:

And I am deleting it like so. I have to do it this way because FreeUploadedVertexData and FreeVertexBuffer pushes the buffer to the front of the list and makes any iterator invalid. I have a feeling my error is in here. I have debugged though and this does go through every node, since every time the node is pushed to the front, back() successfully gets the next one.



FreeVertexBuffer knows about the global list?

A couple of things that can help:
If these are DX vertex buffers check the internal count on Release, make sure that you do not have copies elsewhere that have AddRef'd the buffer intentionally or by accident.

Basically there are two places where the problem might be happening:
Your deallocation loop is not deallocating stuff correctly (Based on your description this does not seem to be the case)
The vertex buffer internal data is not released because the ref count if > 0 after your loop, this might mean some other code is doing an AddRef without a Release (Assuming you are using DX)

Hope this helps
Fruny
Fruny
clear() does not necessarily release the memory owned by the container: it depends on the implementation and the allocator being used. If your containers are global variables, it is very possible that the memory is finally released some time after your leak check.

What STL implementation are you using?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
kuphryn
kuphryn
no matter

without threads, most important is deallocation

Kuphryn
okonomiyaki
okonomiyaki
I thought this went through ealier, but I guess it didn't... (fickle internet here, blah)

These aren't DX buffers, they are simply abstract buffers. Internally I create a few large DX buffers and manage it myself with these buffers.

Thanks for all the help. I tracked down the memory leak to somewhere else, and it's exiting all cleanly now. It was as simple as not deleting something. I guess the allocation request number was different when I ran it with the checkpoint before. Sorry for wasting your time, and thanks :)

By the way, if you read this Fruny, I'm interested, how many different STL implementations are there? I'm just using the standard with Visual Studio 2003.
ldeej
ldeej
Each compiler can have a different implementation, and there are implementations that work with multiple compilers.

VS 2003/2005 ship with two different versions of Dikumware's STL, which is the default and the one you are using right now.

There are some open source ones, i.e. STLPort

Intel and SGI might have implementations as well.
NotAYakk
NotAYakk
Changing the size of a std::vector that contains expensive-to-copy structures like std::lists is not a good idea.

std::vectors are very cavalere about copying their contents around. On average, each call to push_back() on a std::vector costs the copying of one random element already in the vector.

(Every 1/n calls it causes a reallocation, which causes all n elements to be reallocated).

I would advise either storing (auto?)pointers to std::lists, or using a std::deque (which has slower random access, but doesn't copy the data around on you).
Enigma
Enigma
Quote:
Original post by NotAYakk
I would advise either storing (auto?)pointers to std::lists, or using a std::deque (which has slower random access, but doesn't copy the data around on you).

I assume you mean "(smart?)pointers", since auto_ptrs cannot be stored in standard containers.

Σnigma

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.