Archived

This topic is now archived and is closed to further replies.

johnnyBravo

Getting access violations when using class inheritance with cleanup

Recommended Posts

johnnyBravo    100
Im creating a direct3d wrapper. I''ve got classes for each section such as Text, Sprites, Textures, Meshes etc. Each class has the inheritance of D3DDevice class. Which has a cleanup destructor for the "device" It also contains the "LPDIRECT3DDEVICE9 device" I have all the declarations of text, sprite etc in a main class called "Direct3D" so i can call for example:
Direct3D Graphics;
Graphics.Text.Draw("hi",2,2);
The problem is, when i have more than one class declared in "Direct3D", it has access violation when i end my program. I assume this from testing, that it is because I have a number of deconstructors for cleaning up "device". Like one in "Text", another in "Meshes"; So when I close my program it runs a deconstructor in each class, that is Texture, Meshes. When there is only one, there is no problem, but when there is 2 or more, i get the violation. By the way Direct3D also inherits D3DDevice class and also creates the Device. THanks.

Share this post


Link to post
Share on other sites
owl    376
quote:
Original post by johnnyBravo
When there is only one, there is no problem, but when there is 2 or more, i get the violation.


What do you mean by "only one"? How are you storing your objects? Are you using linked lists, arrays?

Give some source, at least the part that trows the error when you debug. Or more pseudo.

Share this post


Link to post
Share on other sites
johnnyBravo    100
Ok heres the class that all my classes are inheriting from

class D3DDevice {
public:
LPDIRECT3DDEVICE9 myDevice;
~D3DDevice() {
if( myDevice != NULL)
myDevice->Release();
}
};


this is my Common class that has render etc, inherits from D3Ddevice


class D3DCommon:public D3DDevice {
public:
void BeginScene(DWORD bgColour, DWORD fgColour)
{
myDevice->SetRenderState( D3DRS_AMBIENT, fgColour );
myDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, bgColour, 1.0f, 0);
myDevice->BeginScene();
}

void EndScene()
{
myDevice->EndScene();
myDevice->Present(NULL, NULL, NULL, NULL );
}
};



and heres my mainish class that declares D3DCommon, creates the device etc. Also inherits D3DDevice so it can use the myDevice to create it...Like put a value in it etc and use it.

class Direct3D:public D3DDevice {
private:
LPDIRECT3D9 myD3D;
public:
~Direct3D()
{
if( myD3D != NULL )
myD3D->Release();
}
D3DCommon Common;
D3DText Text;

void GetDevice()
{
Common.myDevice= myDevice;
}

void Init(HWND hWnd)
{
myD3D = Direct3DCreate9( D3D_SDK_VERSION );
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
myD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &myDevice ) ;
myDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
GetDevice();
}
};



[edited by - johnnyBravo on September 2, 2003 7:21:57 AM]

[edited by - johnnyBravo on September 2, 2003 7:22:42 AM]

Share this post


Link to post
Share on other sites
johnnyBravo    100
Oh i mean if i declare the things like D3DCommon or D3DText

or like what ive got posted now, Direct3D and D3DCommon.

Direct3D without the D3DCommon declared works fine
but when D3DCommon is declared inside of Direct3D i get the violation.
============================
Before that I had it like Direct3D didnt inherit the D3DDevice

and the Init for the device was in D3DCommon.

And when i just had D3DCommon then it worked. As there was only one class actively using the inheritance as the others wern''t declared. But when i declared D3DText aswell it had the violation as there was more than one.

I''m telling you this so you don''t jump to the conclusion that having a class inherit something then a nested class also inheriting the same thing causes this.

Share this post


Link to post
Share on other sites
owl    376
It's hard to me to understand what your saying. Maybe you're releasing your objects more than once? Try seting your objects to NULL after releasing them in the destructor/s.

EDIT:

I mean:

if( myDevice != NULL)
{
myDevice->Release();
myDevice = NULL;
}


[edited by - owl on September 2, 2003 7:48:40 AM]

Share this post


Link to post
Share on other sites
owl    376
well, access violation means that you're trying to access an invalid memory location. This usually happens when you are accessing or deleting an invalid pointer.

It would be very useful if you could press F8 in the first line of all destructors and then run your code and see what line is causing the error. It looks like the destructor is doing something to some pointer there, and then another class is trying to do something with that very same pointer.

edit: ?

[edited by - owl on September 2, 2003 8:20:02 AM]

Share this post


Link to post
Share on other sites
johnnyBravo    100
ah i might have an idea what that would be!

I think the main class Direct3D is being deleted first, as it holds the other classes declarations in itself.

Then maybe the destructors are still trying to delete the myDevices from common etc but they are not there anymore?

Could this be it?

Share this post


Link to post
Share on other sites
johnnyBravo    100
Nope that aint it.

I tried doing this after a bunch of other things

void Unint() {
if( Common.myDevice != NULL)
Common.myDevice->Release();

if( Text.myDevice != NULL)
Text.myDevice->Release();

if( myDevice != NULL)
myDevice->Release();
}


and called uninit before the program ended.

But still getting the same problem, i removed any 2 of the releases(tried different combinations) and it worked.

Could it be that there is really only one myDevice allowed to be called, and the rest are something like pointers. So when one is released, the memory spot is cleared so the rest can find it?

Like the device can have different values etc, but the Release command just releases it all.

[edited by - johnnyBravo on September 2, 2003 9:03:48 AM]

Share this post


Link to post
Share on other sites
dalleboy    324
Common.myDevice and myDevice are probably pointing to the same memory location, and thus they are pointing to the same object. You are calling Release twice(*) for the same object. After the first(**) call to Release the object is destroyed and any further calls will result in an access violation.

* Calling it twice is ok if you have called AddRef when doing the copy.

** Unless you have called AddRef when doing a copy.

So: Call AddRef when doing copies of the pointers and always call Release when you are done with the pointer.

[How To Ask Questions|STL Programmer''s Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]

Share this post


Link to post
Share on other sites
owl    376
You should release/delete your objects in the same class you create them, and only there. When you create an object and you set myDevice to point to it, a number is assigned to myDevice which represents the memory location of that object you created. When you release the object, the object stops to exist, but the pointer may still have some value different from NULL, so checking myDevice!=NULL will be true even when the object was already released.

Again, you NEED to DEBUG your app to KNOW EXACTLY which pointer is getting messed up. I encourage you to find a way to debug your app and see what''s going on.

Share this post


Link to post
Share on other sites
Pothead    130
I can''t understand why all classes inherit from D3DDevice..
I think the proper way would be:

class D3DDevice{
...
}


class D3DCommon{
...
D3DDevice renderer
...
D3DCommon(device):renderer(device){};
}

etc..

I think now all your classes share the device but they still seem to have different device-objects..

Share this post


Link to post
Share on other sites
johnnyBravo    100
Owl i was release etc objects in their own classes at first place until i changed it trying different ways, i even tried putting cleanup in each one and doing it, but same thing.


pothead im doing this because i dont want to use direct3d all the time. like im making this a dx wrapper header.

so i call what i want etc.

All the devices in the end equal the one thing in the end,

Its cuz the way c++ has its classes..
So i guess its all getting cleared up with one release.
Thanks for the help

edit:
I know this must look like a total newbie attempt at something halfbaked, but i can't think of any other way of doing this.

That is making easier functions for the dx commands.

Like say sometimes i just want to use Direct Input for the keyboard.
Then other times i might want to use D3D with only basic vertices and Direct Input mouse.

I want to do this without declaring anything, but I want all the methods there incase i do.
With all this stored in a header file.

If anyone knows a better solution to this, I'd be really really grateful.

[edited by - johnnyBravo on September 2, 2003 9:55:24 AM]

[edited by - johnnyBravo on September 2, 2003 9:56:15 AM]

[edited by - johnnyBravo on September 2, 2003 9:57:08 AM]

Share this post


Link to post
Share on other sites