dx - memory leak, but I really can't see where

Started by
10 comments, last by Evil Steve 15 years, 9 months ago
DirectX reports a memory leak, I know it's in the texture code because if I don't create a texture theres no leak...but I can't see how since I'm releasing the texture interface, and the destruture is called because ive checked that...

	Texture* TextureCreateFromFile (Core* Owner, const std::string &Path)
	{
		LibTexture *NewTex = new LibTexture;
		NewTex->Owner = Owner;

		D3DXIMAGE_INFO Info;
		if(FAILED(D3DXCreateTextureFromFileEx(
			((LibCore*)Owner)->D3dDevice, Path.c_str(),
			NULL,NULL, 1, 0, D3DFMT_A8R8G8B8,
			D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT,
			NULL, &Info, NULL, &NewTex->Tex)))
		{
			delete NewTex;
			return NULL;
		}
		NewTex->h = Info.Height;
		NewTex->w = Info.Width;
		return NewTex;
	}
	LibTexture::~LibTexture()
	{
		if(Tex)Tex->Release();
	}


Advertisement
There's no leak in that code. I suspect it's caused by you failing to delete a texture, which would cause your destructor not to be called, and the texture not to be Release()d.
Wells theres only one texture for the purpose of testing, and if I didn't delete it, then the app wouldn't end either...

void Update(fw::Core *This){	if(This->WndClose)	{		delete Circle;//<-- deleted here		This->DestroyAll();//<--cleans up the base d3d stuff (D3dDevice, basic vertex buffer, etc) + destroys the window	}}


[Edited by - Sync Views on June 24, 2008 12:51:37 PM]
Quote:Original post by Sync Views
Wells theres only one texture for the purpose of testing, and if I didn't delete it, then the app wouldn't end either...

*** Source Snippet Removed ***


Are you manually calling a destructor? Can you copy and paste your full code?
no..that doesn't even compile I don't think lol...I trtied simpifiing it so that it wasn't a bunch of iterating and screwed it up lol... Either way it's getting decontructed at the right point because I put a break point in their to see if it was getting decontruted..
you need to put up the code that's calling the texture creation steps.

Looking at your code, you may not be releasing the contents of the buffer, while your releasing the buffer the contents may still be held in memory.

i found that when the buffer was released the texture variable still held the memory spaces for the buffer, Nulled it out in the deconstruction process and it seemed to fix it.
test.cpp
Texture* Circle = NULL;void StartUp(fw::Core *This)//called just before entering the message loop{	Circle = TextureCreateFromFile(This, "circle.png");}void Update(fw::Core *This)//called 30 times a second{	if(This->WndClose)	{		Circle->Release();		This->DestroyAll();	}}


dll
texture.h
...	class Texture	{		public:		virtual void Release()=0;		virtual unsigned GetW()=0;		virtual unsigned GetH()=0;		//draw functions		virtual bool Draw(const math::Matrix<4,4> &Transform)=0;	};	DLL Texture* TextureCreateFromFile    (Core* Owner, const std::string &Path);	DLL Texture* TextureCreateFromFileMem (Core* Owner, void *Men, unsigned Length);	DLL Texture* TextureCreateFromResource(Core* Owner, const std::string &Res);	//note: the bit after this is not in the import header, the rest is	class LibTexture : public Texture	{		public:		IDirect3DTexture9* Tex;		unsigned w,h;		Core* Owner;		LibTexture();		virtual void Release();		virtual unsigned GetW();		virtual unsigned GetH();		virtual bool Draw(const math::Matrix<4,4> &Transform);//not tested, or used yet	};

texture.cpp
	Texture* TextureCreateFromFile (Core* Owner, const std::string &Path)	{		LibTexture *NewTex = new LibTexture;		NewTex->Owner = Owner;		D3DXIMAGE_INFO Info;		if(FAILED(D3DXCreateTextureFromFileEx(			((LibCore*)Owner)->D3dDevice, Path.c_str(),			NULL,NULL, 1, 0, D3DFMT_A8R8G8B8,			D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT,			NULL, &Info, NULL, &NewTex->Tex)))		{			delete NewTex;			return NULL;		}		NewTex->h = Info.Height;		NewTex->w = Info.Width;		return NewTex;	}	Texture* TextureCreateFromFileMem(Core* Owner, void *Mem, unsigned Length)	{...	}	Texture* TextureCreateFromResource(Core* Owner, const std::string &Res)	{...		}	LibTexture::LibTexture()		:Tex(NULL)	{}	unsigned LibTexture::GetW()	{		return w;	} 	unsigned LibTexture::GetH()	{		return h;	}	void LibTexture::Release()	{		if(Tex)Tex->Release();		delete this;	}	bool LibTexture::Draw(const math::Matrix<4,4> &Transform)	{		float *m = new float[4*4];		for(int x=0; x<4; ++x)			for(int y=0; y<4; ++y)				m[x + y*4] = (float)Transform.m[x][y];//I really need a better way to get froma  4x4 array of doubles to a 16 array of floats...		D3DXMATRIX D3dMat(m);		((LibCore*)Owner)->D3dDevice->SetTexture(0, Tex);		((LibCore*)Owner)->D3dDevice->SetTransform(D3DTS_WORLD, &D3dMat);		if(FAILED(((LibCore*)Owner)->D3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2)))		{			log::Add(log::Error, "Texture::Draw", "Failed to textured quad");			return false;		}		else return true;	}

Appart from the d3d startup/destroy functions (which just create a device + vertex buffer with 4 verteces for a 1x1 quad around 0,0) that is all my directX code... Just those 2 calls in my start and update exist...
have you tried putting a break point right at the start of the the test.cpp code, open task manager (if your on a windows box obviously) and let the code run through, if it comes back to the start of test.cpp then you know its looping and creating the texture over and over. You will also be able to see easier (at least i find) where memory is being allocated and so forth.
What's in fw::Core::DestroyAll()?
void LibCore::DestroyAll(){	quiting = true;//stops the loop from calling Update, or Render again (if it was to do so, crashes are almost certain)	D3dDestroy();	DestroyWindow(Wnd);}void LibCore::D3dDestroy(){	BackBuffer->Release();//I get this at the start, such that I can put the render target back if I ever change it	VertexBufferBase->Release();//Currently just holds 4 vertices froa  quad around 0,0	D3dDevice->Release();	D3d->Release();}

This topic is closed to new replies.

Advertisement