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

Problem with Destructors

Started by CloudNine May 15, 2003 at 1:56 AM 10 replies 500+ views
Original Post
CloudNine
CloudNine
I''ve been coding away at my DirectX Wrapper again, but I seem to have run into another problem. Try this zip: http://www.bluefirestudios.com/inbound/DXW.zip It never seems to call the destructor, as a message box never comes up when D3D devices are destroyed, so I guess it''s a case of a memory leak Any ideas? CloudNine
CloudNine
CloudNine
The offending bits of code:

CApplication.cpp

  
#include "Main.h"

CGOApp::CGOApp() //The constructor

{
windowalive=true;
gD3D=NULL;
gD3Ddevice=NULL;
}

CGOApp::~CGOApp() //The destructor

{
goKillD3D();
}

bool CGOApp::goInitWindow(char wtitle[32],int wwidth,int wheight,HINSTANCE hInstance,DWORD wstyle,bool wfullscreen) //Initiates the window

{
strcpy(title,wtitle);
width=wwidth;
height=wheight;
dwStyle=wstyle;
fullscreen=wfullscreen;

if (fullscreen)
{
dwStyle=WS_POPUP;
}

wc.cbSize=sizeof(WNDCLASSEX);
wc.style=CS_OWNDC;
wc.lpfnWndProc=WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName=title;
wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);

RegisterClassEx(&wc);

hWnd=CreateWindowEx(0,title,title,dwStyle,
0,0,width,height,NULL,NULL,
hInstance,NULL);

ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);

goInitD3D();

return true;
}

void CGOApp::goWindowKill()
{
windowalive=false;
}

void CGOApp::goInitD3D()
{
gD3D=Direct3DCreate8(D3D_SDK_VERSION);
if (!gD3D) goRunTimeError("Error getting DirectX 8");

hR=gD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&displaymode);
if (FAILED(hR)) goRunTimeError("Error getting adapter display mode");

ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow=hWnd;
d3dpp.BackBufferCount=1;

//Z buffer stuff


d3dpp.EnableAutoDepthStencil=true;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;

if (fullscreen)
{
d3dpp.Windowed=false;
d3dpp.BackBufferWidth=width;
d3dpp.BackBufferHeight=height;

d3dpp.BackBufferFormat=FindBitMode();
}else{

d3dpp.Windowed=true;
d3dpp.BackBufferFormat=displaymode.Format;
}

hR=gD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&gD3Ddevice);

if (FAILED(hR)) goRunTimeError("Error creating D3D device");

}

void CGOApp::goMessageLoop()
{
if(GetMessage(&messages,NULL,0,0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}

D3DFORMAT CGOApp::FindBitMode()
{
hR=gD3D->CheckDeviceType(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
D3DFMT_R5G6B5,
D3DFMT_R5G6B5,
FALSE);

if (SUCCEEDED(hR)) return D3DFMT_R5G6B5;

hR=gD3D->CheckDeviceType(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
D3DFMT_X1R5G5B5,
D3DFMT_X1R5G5B5,
FALSE);

if (SUCCEEDED(hR)) return D3DFMT_X1R5G5B5;

goRunTimeError("Couldn''t find a 16bit color format");
}

void CGOApp::goKillD3D()
{
if (gD3Ddevice)
{
gD3Ddevice->Release();
gD3Ddevice=NULL;
}

if (gD3D)
{
gD3D->Release();
gD3D=NULL;
}

goRunTimeError("D3D killed properly");
}

void CGOApp::Cls()
{
gD3Ddevice->Clear(0,
NULL,
D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0),
1.0f,
0);
}

void CGOApp::Cls(GOBYTE r,GOBYTE g,GOBYTE b)
{
gD3Ddevice->Clear(0,
NULL,
D3DCLEAR_TARGET,
D3DCOLOR_XRGB(r,g,b),
1.0f,
0);
}

void CGOApp::BeginScene()
{
gD3Ddevice->BeginScene();
}

void CGOApp::EndScene()
{
gD3Ddevice->EndScene();
}

void CGOApp::Flip()
{
gD3Ddevice->Present(NULL,
NULL,
NULL,
NULL);
}


and Main.cpp

  
#include "main.h"

CGOApp cApp; //The application instance


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmd, int nShow)
{
cApp.goInitWindow("BlueFireStudios Windows Wrapper",800,600,hInstance,CGO_NORMAL,CGO_FULLSCREEN);

while (cApp.goWindowAlive())
{
cApp.goMessageLoop();
Render();
}
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
DestroyWindow(hWnd);
cApp.goWindowKill();
break;
case WM_QUIT:
case WM_DESTROY:
case WM_KEYDOWN:
PostQuitMessage(0);
cApp.goWindowKill();
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}

void Render()
{
cApp.Cls(255,0,0);
cApp.BeginScene();
cApp.EndScene();
cApp.Flip();
}


A message box should come up that the window and D3D have been killed properly, but that''s in theory

CloudNine
CloudNine
CloudNine
Does cApp being global affect how the destructor is called?
tr0n
tr0n
IIRC, Visual C++ has a ''feature'' whereby destructors aren''t called for global objects. I may be wrong there, though.
CloudNine
CloudNine
I''m using Dev C++, so would that be the case?
tr0n
tr0n
Not sure about Dev-C++, as I''ve never used it...

If it seems that the destructor isn''t being called, try making a function to run at app exit, and explicitly call the destructor(s). Then, if your message still doesn''t appear, then something else is happening...
CloudNine
CloudNine
Yup, I tried calling goKillD3D() right at the end of WinMain, but that didn''t work
billybob
billybob
PostQuitMessage/WM_QUIT disables MessageBox. the most incredibly retarded ''feature'' of windows there is, believe me i''ve spent a total of a week at LEAST trying to get around it. windows really really kills those message boxes dead after WM_QUIT. it might be DestroyWindow, but i''m pretty sure it was WM_QUIT (DestroyWindow probably calls PostQuitMessage for that thread)
CloudNine
CloudNine
So how would I check the D3D interfaces were being destroyed?
billybob
billybob
log file? i can almost gaurentee you the destructor is being called.
billybob
billybob
make sure your logger flushes the buffer at least frequently, if not after every log output. otherwise, if it crashes, nothing will show up because it won''t get written until the file is closed - which never happens in a crash.

Topic Locked

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

Sign in to reply to this topic.