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

STD Linked Lists

Started by dawidjoubert Jul 29, 2006 at 5:54 PM 3 replies 1.9k views
Original Post
dawidjoubert
dawidjoubert
Hey I am using STL LIST as my data managing thingy but I am getting a problem: Here is the code that gives off the problem: The list are empty initially



	CSceneObject *o=NULL;
	if (m_lTempelateObject.size() == 0)
	{
		// Create default tempelates
		// Create Terrain
		o = AddTempelateObject(this->eTerrain);
		o->isCollideable = true;
		// Create 
		o = AddTempelateObject(this->eGravity);  <--- ERROR COMES HERE ACCORDING TO DEBUGGER
		o->isCollideable = true;
	}

CSceneObject *CScene::AddTempelateObject(int id,bool loadmodel)
{
	CSceneObject temp;
	m_lTempelateObject.push_back(temp);	<--- ERROR TRACED THROUGH HERE
	if (m_lTempelateObject.size() == 0) 
	{
		itObject = m_lTempelateObject.begin();
	}
	else itObject = m_lTempelateObject.end();
	CSceneObject *o = &(*itObject);
	o->TempelateID = id;
	if (loadmodel) o->LoadModelByID(id);
	return o;
};

	void push_back(const _Ty& _Val)
		{	// insert element at end
		_Insert(end(), _Val);   <--- TRACED THROUGH HERE
		}

	void _Insert(iterator _Where,
		const _Ty& _Val)
		{	// insert _Val at _Where
		_Nodeptr _Pnode = _Where._Mynode();
		_Nodeptr _Newnode = _Buynode(_Pnode, _Prevnode(_Pnode), _Val); <-- THROUGH HERE
		_Incsize(1);
		_Prevnode(_Pnode) = _Newnode;
		_Nextnode(_Prevnode(_Newnode)) = _Newnode;
		}

	_Nodeptr _Buynode(_Nodeptr _Next,
		_Nodeptr _Prev, const _Ty& _Val)
		{	// allocate a node and set links and value
		_Nodeptr _Pnode = this->_Alnod.allocate(1); <-- THROUGH HERE
		_TRY_BEGIN
		new ((void *)_Pnode) _Node(_Next, _Prev, _Val);
		_CATCH_ALL
		this->_Alnod.deallocate(_Pnode, 1);
		_RERAISE;
		_CATCH_END
		return (_Pnode);
		}

	pointer allocate(size_type _Count)
		{	// allocate array of _Count elements
		return (_Allocate(_Count, (pointer)0)); <-- OBVIOUSLY THROUGH HERE
		}

		// TEMPLATE FUNCTION _Allocate
template<class _Ty> inline
	_Ty _FARQ *_Allocate(_SIZT _Count, _Ty _FARQ *)
	{	// allocate storage for _Count elements of type _Ty
		return ((_Ty _FARQ *)operator new(_Count * sizeof (_Ty))); <-- THROUGH HERER
	}

jmp         operator new+4 (4345F4h)   <-- THROUGH HERE (THis is apparently a new function)

00434858  push        offset __TI2?AVbad_alloc@std@@ (464260h) <-- HERE it pushes a BAD ALLOC onto the warning stack or what ever and then it reaches me




HERE IS THE TRACE STACK:
>	physics.exe!strlen()  Line 78	Asm
 	physics.exe!exception::exception(const exception & that={...})  + 0x31	C++
 	physics.exe!std::bad_alloc::bad_alloc(const std::bad_alloc & __that={...})  + 0x13	C++
 	physics.exe!std::_Nomemory()  Line 9 + 0xd	C++
 	physics.exe!operator new(unsigned int size=184)  Line 15	C++
 	physics.exe!std::_Allocate<std::_List_nod<CSceneObject,std::allocator<CSceneObject> >::_Node>(unsigned int _Count=1, std::_List_nod<CSceneObject,std::allocator<CSceneObject> >::_Node * __formal=0x00000000)  Line 34 + 0xf	C++
 	physics.exe!std::allocator<std::_List_nod<CSceneObject,std::allocator<CSceneObject> >::_Node>::allocate(unsigned int _Count=1)  Line 137 + 0xb	C++
 	physics.exe!std::list<CSceneObject,std::allocator<CSceneObject> >::_Buynode(std::_List_nod<CSceneObject,std::allocator<CSceneObject> >::_Node * _Next=0x00e42e68, std::_List_nod<CSceneObject,std::allocator<CSceneObject> >::_Node * _Prev=0x00e40ff0, const CSceneObject & _Val={...})  Line 918 + 0xa	C++
 	physics.exe!std::list<CSceneObject,std::allocator<CSceneObject> >::_Insert(std::list<CSceneObject,std::allocator<CSceneObject> >::iterator _Where={...}, const CSceneObject & _Val={...})  Line 523 + 0x1f	C++
 	physics.exe!std::list<CSceneObject,std::allocator<CSceneObject> >::push_back(const CSceneObject & _Val={...})  Line 482	C++
 	physics.exe!CScene::AddTempelateObject(int id=1, bool loadmodel=true)  Line 8	C++
 	physics.exe!CScene::LoadObjectTempelate(char * filename=0x004601a1)  Line 33 + 0xc	C++
 	physics.exe!GameInit()  Line 114	C++
 	physics.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00141f07, int nCmdShow=1)  Line 138	C++
 	physics.exe!WinMainCRTStartup()  Line 251 + 0x30	C


COuld you please help me out Basically it says no memory error but i cant understand why!! I have 1.5GB and only 400MB is being used!
----------------------------http://djoubert.co.uk
SiCrane
SiCrane
The most likely cause of a std::bad_alloc exception is heap corruption. This can occur due to a buffer overrun that damages the book keeping data that the CRT uses to keep track of allocations. Unfortunately, this means that your problem is likely actually somewhere removed from the code that you traced through.
scottdewald
scottdewald
Just a side note... if you want to test if an STL container is empty, don't use (container.size() == 0). Instead, use (container.empty()). Some implementations may actually have to traverse the entire container to check the size before you compare it to 0, and all you want to know is if there are any items in the container.
smart_idiot
smart_idiot
In CScene::AddTempelateObject(int id, bool loadmodel)...
m_lTempelateObject.push_back(temp);
if (m_lTempelateObject.size() == 0)

How can it be empty if you've just pushed something into it? Also, scottdewald is 100% correct about using empty() instead.
else itObject = m_lTempelateObject.end();
CSceneObject *o = &(*itObject);

end() doesn't point to the last element, it's ONE PAST the last element. You must never dereference it, it doesn't point to a valid object! The memory for it may or may not exist, and it most definitely hasn't been initialized yet. (FYI, back() returns a reference to the last object, that's the function you want.)
o->TempelateID = id;
if (loadmodel) o->LoadModelByID(id);
return o;

Oh, damn, now you're using an invalid object.


CSceneObject *CScene::AddTempelateObject(int id,bool loadmodel){	m_lTempelateObject.push_back(CSceneObject());	CSceneObject *o = &m_lTempelateObject.back();	o->TempelateID = id;	if (loadmodel) o->LoadModelByID(id);	return o;};
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other
dawidjoubert
dawidjoubert
Quote:
Original post by smart_idiot
In CScene::AddTempelateObject(int id, bool loadmodel)...
m_lTempelateObject.push_back(temp);
if (m_lTempelateObject.size() == 0)

How can it be empty if you've just pushed something into it? Also, scottdewald is 100% correct about using empty() instead.
else itObject = m_lTempelateObject.end();
CSceneObject *o = &(*itObject);

end() doesn't point to the last element, it's ONE PAST the last element. You must never dereference it, it doesn't point to a valid object! The memory for it may or may not exist, and it most definitely hasn't been initialized yet. (FYI, back() returns a reference to the last object, that's the function you want.)
o->TempelateID = id;
if (loadmodel) o->LoadModelByID(id);
return o;

Oh, damn, now you're using an invalid object.


*** Source Snippet Removed ***


Thanks a lot. That is however not the error since i appended your changes. No I found the error comes from a data corruption in the loadModelByID() as it opens a text files and reads it.

Quote:
Original post by scottdewald
Just a side note... if you want to test if an STL container is empty, don't use (container.size() == 0). Instead, use (container.empty()). Some implementations may actually have to traverse the entire container to check the size before you compare it to 0, and all you want to know is if there are any items in the container.


Excellent point..

[Edited by - dawidjoubert on July 30, 2006 8:24:16 PM]
----------------------------http://djoubert.co.uk

Topic Locked

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

Sign in to reply to this topic.