Releasing class member D3D objects

Started by
4 comments, last by eltharynd 10 years, 7 months ago

So i have a class that handles all of the D3D parts of my program...

That class has the following members:


public:
	IDXGISwapChain* pSwapChain;
	DXGI_SWAP_CHAIN_DESC scd;
	ID3D11Device* pDevice;
	ID3D11DeviceContext* pDeviceContext;
	ID3D11RenderTargetView* pBackBuffer;

now in my class deconstructor i automatically call its member function


	void CleanD3D();

which has the following implementation:


void Engine::CleanD3D()
{
	pSwapChain -> Release();
	pBackBuffer -> Release();
	pDevice -> Release();
	pDeviceContext -> Release();
}

So my main function creates an object with the Engine class, and everything goes fine.

But when i try to quit the application i call the D3D function to release everything and the program breaks... i actually have no idea why and i don't think the memory is freed...

any suggestions?


First-chance exception at 0x0134B79D in Space.exe: 0xC0000005: Access violation reading location 0x005E99E8.
Unhandled exception at 0x0134B79D in Space.exe: 0xC0000005: Access violation reading location 0x005E99E8.
Advertisement

I'm not sure but there might be proper release order. Try to release backbuffer before swapchain and devicecontext before device.

What line does it stop on? Have you stepped through line by line?
Are all those variables initialized properly in the constructor?
Do you ever (accidentally or not) make copies of the Engine class object?
You can detect accidental copying by defining private copy constructor and assignment operators. This will generate compiler errors anywhere where the class is being copied.
class Engine
{
...
private:
  Engine( const Engine& );
  Engine& operator=( const Engine& );
}

Before Releasing any D3D object you should first check if the object is NULL or not; this will help protect you against cases where your destructor needs to run after failing to create an object. Then, after Releasing an object, you should make it NULL to help protect you if you accidentally call your CleanD3D twice (of course you should fix the design issue that caused you to release it twice too).

This won't solve your immediate problem but it will make your program more robust overall.

Regarding your immediate problem, does your CleanD3D run before or after you destroy your application window? If after, you should move it to before, as D3D objects have a dependency on the window existing.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


Before Releasing any D3D object you should first check if the object is NULL or not; this will help protect you against cases where your destructor needs to run after failing to create an object. Then, after Releasing an object, you should make it NULL to help protect you if you accidentally call your CleanD3D twice (of course you should fix the design issue that caused you to release it twice too).

Or, better yet, encapsulate at least those 4 classes into one wrapper class, and instead of a cleanup-call release in the destructor. This resolved the need for setting them to null, and will also hinder you from accidentially calling it twice in the first place (you destroy the wrapper object for cleanup). Encapsulating/wrapping those might be a good idea anyway, if you have those pointer dangling around unprotected god knows what can happen - like you accidentially release them somewhere else, over overwrite them...

thanks everybody for the help... the problem was indeed what you said... i managed to fix this anyway


Engine::~Engine()
{
	if(pSwapChain) pSwapChain -> Release();
	if(pBackBuffer) pBackBuffer -> Release();
	if(pDevice) pDevice -> Release();
	if(pDeviceContext) pDeviceContext -> Release();
} 

if anyone needs it

This topic is closed to new replies.

Advertisement