Jump to content
  • Advertisement
Sign in to follow this  
Dan Caranfil

Problem cleaning a list with LPD3DXMESH objects

This topic is 4873 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[I have edited my original post for the sake of clarity] I have several meshes in my game. Some of them are stored in a STL list container. At the end of the game I want to release all my meshes. I can release all my meshes with no problem except the meshes from the list. When it comes to releasing the list objects I recive this error:'MyGame.exe has triggered a breakpoint' and a indicator to the line where the mesh materials array is being deleted. My mesh shutdown code looks like this (I took this from a 32Bits tutorial):

HRESULT MeshObjMold::ShutDown()
{	
	// Free the materials array
	if(m_pMaterials)
	      delete [] m_pMaterials;  // This is the place where the error occurs

	if(m_pTextures)
	{
		for(int iCount = 0; iCount < (int)m_dwNumMaterials; iCount++)
		{
			m_pTextures[iCount]->Release();
			m_pTextures[iCount] = NULL;
		}

		delete [] m_pTextures;
	}

	// Release the mesh object
	if(m_pMesh)
		m_pMesh->Release();

	m_dwNumMaterials = 0;
	m_pMaterialsBuffer = NULL;
	m_pMaterials = NULL;
	m_pTextures = NULL;
	m_pMesh = NULL;

	return D3D_OK;
}




Any ideea or suggestion on how to solve this problem is welcomed. [Edited by - Dan Caranfil on November 21, 2005 7:40:38 AM]

Share this post


Link to post
Share on other sites
Advertisement
hi,

the code seems correct, but you need to give us the error you're having, and how you initialized / filled the m_pMaterials variable for further help ^^

Share this post


Link to post
Share on other sites
Thanks for input

Quote:

you need to give us the error you're having

The game crashes when I press the exit button. When I run the debugger I revice this error: 'MyGame.exe has triggered a breakpoint' and a indicator to the line I mentioned.


The initialization code looks like this:


HRESULT MeshObjMold::Initialise(char *szMeshFile, LPDIRECT3DDEVICE9 &pDevice)
{

HRESULT rslt = D3D_OK;

// First, load the .X file into a mesh object, and fill out the materials buffer
rslt = D3DXLoadMeshFromX(szMeshFile, D3DXMESH_MANAGED, pDevice, NULL,
&m_pMaterialsBuffer, NULL, &m_dwNumMaterials, &m_pMesh);

if(FAILED(rslt)) {
dhLog("Failed to load mesh from file",rslt);
}


//Get a pointer to the first element of data in the materials buffer, ready to read out.
D3DXMATERIAL* pMaterials = (D3DXMATERIAL*)m_pMaterialsBuffer->GetBufferPointer();

// Create 2 arrays, 1 for textures and 1 for materials. D3DXLoadMeshFromX puts the
// number of materials/textures (always the same) into m_dwNumMaterials above.
m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials];
m_pTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];

// Next, iterate through the pMaterials buffer.
{
for(int iCount = 0; iCount < (int)m_dwNumMaterials; iCount++)
{
// For each material buffer element, copy the D3DMATERIAL into this class' array.
m_pMaterials[iCount] = pMaterials[iCount].MatD3D;

m_pMaterials[iCount].Ambient = m_pMaterials[iCount].Diffuse;

// Finally, create a texture from the file specified in the mateirals buffer and put
// it in the m_pTextures array.
rslt=D3DXCreateTextureFromFile(pDevice, pMaterials[iCount].pTextureFilename, &m_pTextures[iCount]);
if(FAILED(rslt)) {
dhLog("Failed to load mesh texture from file",rslt);
}
}
}

m_pMaterialsBuffer->Release();
m_pMaterialsBuffer = NULL;

return D3D_OK;
}









Call the Initialization function and fill the container list:



ObjectScene.OBt[0].Initialise("Objects3D/O00.x",g_d3d_device);
ObjectScene.OBt[1].Initialise("Objects3D/O01.x",g_d3d_device);
ObjectScene.OBt[2].Initialise("Objects3D/O02.x",g_d3d_device);
ObjectScene.OBt[3].Initialise("Objects3D/O03.x",g_d3d_device);
ObjectScene.OBt[4].Initialise("Objects3D/O04.x",g_d3d_device);
ObjectScene.OBt[5].Initialise("Objects3D/O05.x",g_d3d_device);
ObjectScene.OBt[6].Initialise("Objects3D/O06.x",g_d3d_device);


//[code removed]

Fill the list
//
if(GameMenu.ObjectsMI.SubmenuIButt[0].Down && MS.LBDown){


ObjectList.push_back(OBt[0]);

}
if(GameMenu.ObjectsMI.SubmenuIButt[1].Down && MS.LBDown){


ObjectList.push_back(OBt[1]);

}


// Clear the list at the end of the game

for (list <SimpleOMold>::iterator i = ObjectList.begin(); i != ObjectList.end(); ++i)
{

hr= i->ShutDown();
}










One more thing: I get this problem only with meshes that are stored in the container.

[Edited by - Dan Caranfil on November 21, 2005 6:08:56 AM]

Share this post


Link to post
Share on other sites
Do you have some code in the desctructor of MeshObjMold ?? If yes, can you post it also ?

Imagine the piece of code :


class CFoo
{
char *m_str;

public:
CFoo(void) { m_str = NULL; }
~CFoo(void) { delete [] m_str; }

void Initialize(void) { m_str = new char [256]; }
};


// somewhere :
CFoo *str = new CFoo;
str.Initialize(); // here, all is ok

// here, a copy of the CFoo instance is created and sent to aFunction()
// so, both str and the copy have a m_str pointer pointing to the same
// memory location. So, when the compiler reach the end of aFunction, it
// will destroy the copy, calling its destructor, which will free m_str
aFunction(str);

// so the following line will fail :
// at this point, the m_str was already deleted, and your app crash
delete str;



When dealing with containers, it's better to provide copy constructors to avoid those kind of problem (in your class, if you destroy m_pMaterials in the destructor, then it's this problem)

In the previous example, you solve the problem by doing this :


class CFoo
{
protected:
char *m_str;

public:
CFoo(void) { m_str = NULL; }
~CFoo(void) { delete [] m_str; }

void Initialize(void) { m_str = new char [256]; }

// copy constructor
CFoo(CFoo & copy)
{
if (this != &copy)
{
if (copy.m_str)
{
m_str = new char [256];
memcpy(m_str, copy.m_str, 256);
}
}
}

};



This way, when a copy will be created, a new m_str will be created and the destructor won't touch the original object.

Share this post


Link to post
Share on other sites
I have a distructor function but it`s empty:
MeshObjMold::~MeshObjMold()
{


}
I decided to keep it this way because of an overkilling problem I had in the past. I always use the shutdown function posted above then I have to clean up.

Share this post


Link to post
Share on other sites
That's strange, this kind of error happen usually when you try to delete something that was already deleted ...
If you can post your project somewhere on the web and give me a link to the archive, I might have a look. I can't help more than that without compiling and debugging the code, sorry :/

Share this post


Link to post
Share on other sites
Thanks for helping me out.

Quote:
Original post by paic
That's strange, this kind of error happen usually when you try to delete something that was already deleted ...
If you can post your project somewhere on the web and give me a link to the archive, I might have a look. I can't help more than that without compiling and debugging the code, sorry :/


Well I think you have pointed already the source of the problem: I was using the default copy constructor, a practice that is not recomended when your class has pointers ( I found this after I read you post).
Anyway I will PM you the link to my project, I haven`t solved this problem yet and I need all the help I can get.


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!