Advertisement

[D3D9] Memory Leak stemming from D3DXLoadMeshFromX

Started by May 03, 2011 12:11 AM
10 comments, last by Mussi 13 years, 4 months ago
Hey guys, I am having problems with a memory leak when trying to load meshes and textures into a map structure. I've been trying to use something like this to load the data:

D3DXLoadMeshFromX( meshName, D3DXMESH_SYSTEMMEM, gfx3DDevice, NULL, &tempMaterialBuffer, NULL,
&_tempNumMaterials, &_meshes[assetName] );


where the map is declared as:

map<LPCWSTR, LPD3DXMESH> _meshes;

I've tried looking into varous fixes but the only way I can get rid of the memory leaks is by de-allocating within the same function where I am loading the resources. I am making sure to properly de-allocate them later in the destructor method of the class but apparently that has no bearing on the leaks. Does anyone have any ideas as to why this is happening? Thanks in advance.
How do you deallocate your meshes?
Advertisement
for (map<LPCWSTR, LPD3DXMESH>::iterator i = _meshes.begin(); i != _meshes.end(); ++i)
{
if (i->second != NULL)
{
i->second->Release();
}
}
_meshes.clear();
That seems like the correct way to do it, are you sure this is getting executed?

D3DXLoadMeshFromX( meshName, D3DXMESH_SYSTEMMEM, gfx3DDevice, NULL, &tempMaterialBuffer, NULL,
&_tempNumMaterials, &_meshes[assetName] );


Are you sure you're not using duplicate key values with assetName? I'm not sure if it matters, but does the assetName key already exist in the map before calling the function?
I've made sure, stepped through the code multiple times now and it is definately called. When I comment out this method or release immediately afterwards then I don't get any memory leaks. The key does not exist already in the map. I'll try that and see if it works.
That hasn't seemed to make a difference, although I'll keep playing around with it in the hopes that I can discover the problem.
Advertisement

I've made sure, stepped through the code multiple times now and it is definately called. When I comment out this method or release immediately afterwards then I don't get any memory leaks. The key does not exist already in the map. I'll try that and see if it works.


Seems like the pointers that you're storing don't match up, is this noticeable during runtime? If so, you should check for errors when calling D3DXLoadMeshFromX. And for good practice's sake you should also check for errors if it's not :P. Are you sure you're not using duplicate key values?
The pointers definately match up. I've been using my ResourceManager class for a while now and have had no issues using it to load resources. I'll make sure to look into error checking. Key values are definately not duplicated. However, after checking through the memory leaks from the DirectX Control Panel in Output, it would appear that the first memory leak is actually stemming not from the resource manager, but from the following line:

_gfx3DInterface = Direct3DCreate9( D3D_SDK_VERSION );
Post I found that might be helpful: http://www.gamedev.net/topic/149372-tracking-a-memory-leak-in-d3d9/

2) With leak tracking it''s often a good idea to start at the *LAST* AllocID and work up the list since the objects at the top will be parent objects (as you''re seeing when you look at the call stack).

3) For debugging purposes you can check the return value from your Release() calls to determine their refcounts.
[/quote]
I managed to track down the memory leak using your help, and it turns out it's not because of the mesh at all! It's because of the texture file which I'm loading! It's a similar case to the Mesh, but I'll provide the important parts of code:

map<LPCWSTR, LPDIRECT3DTEXTURE9*> _textures;

// Gets the number of textures and materials to load
loadedMaterials = (D3DXMATERIAL*) tempMaterialBuffer->GetBufferPointer();
_textures[assetName] = new LPDIRECT3DTEXTURE9[_tempNumMaterials];
_materials[assetName] = new D3DMATERIAL9[_tempNumMaterials];

// For the number of loaded materials
for ( DWORD i = 0; i < _tempNumMaterials; i++ )
{
// Loads the materials
_materials[assetName] = loadedMaterials.MatD3D;
_materials[assetName].Ambient = _materials[assetName].Diffuse;

// Loads the textures
_textures[assetName] = NULL;
if ( loadedMaterials.pTextureFilename != NULL )
{
D3DXCreateTextureFromFileA( gfx3DDevice, loadedMaterials.pTextureFilename, &_textures[assetName] );
}
}

tempMaterialBuffer->Release();


This above piece of code carries on from the LoadMeshFromX call.

Then finally, in the destructor call:

for (map<LPCWSTR, LPDIRECT3DTEXTURE9*>::iterator i = _textures.begin(); i != _textures.end(); ++i)
{
if (i->second != NULL)
{
int numObjects = sizeof(i->second) / sizeof(LPDIRECT3DTEXTURE9*);

for (int j = 0; j < numObjects; ++j)
{
i->second[j]->Release();
}
}
}


I'm going to try and track it down tonight before I head to bed, but if anyone finds anything and wishes to share, would be very much appreciated :)

This topic is closed to new replies.

Advertisement