Skip to main content
gamedev.net
🔒 Locked

Odd destructor

Started by IO Fission Oct 2, 2000 at 1:27 AM 13 replies 400+ views
Original Post
IO Fission
IO Fission
I''ve made a wrapper class for a Direct Draw surface. I''ve set up methods for creating, destroying, and other tasks. I added a constructor that initialises pointers to NULL, thus preventing the attempted destruction of and surface not created. This is al well and good, so I decide to add a desctructor to call the destroy method so that all surfaces are DEFINATELY destroyed. This makes sense to me, so why does the program die as soon as I create the class? First I set up the display (wrapped in another class), then I try to create a surface using my wrapper. The program promptly shuts down and quits. No errors. No "unable to create surface". Run it and it just flashes a black screen at me, and quits. I can''t understand how (or even why) the destructor could be called AND shut down the program, considering that: A: The destructor shouldn''t be called there. B: The pointer is NULL ( according to the constructor ), and so therefor cannot be destroyed because the function will only destroy a valid pointer (ie !=NULL) Is there something I dont know about? Any ideas? "If you have any questions you may direct
them to that brick wall over there." - South Park
sayshell
sayshell
maybe if you have declarations like

void smth() {
CWrapper s;
s.Init();
return;
}

when you exit the function the destructor is called as the stack has to be cleared from the CWrapper object ?
IO Fission
IO Fission
What I have in WinMain is equivalent to this:

    {
MSG msg;
// one or two more irrelevant variables


SetupApp(); // Sets up the display, instance, and timer routines.

CSurface DamnThing; // At this point the program commits suicide.


// Message loop stuff

}


When I remove the destructor everything runs fine.
It's as if the destructor is called BEFORE the constructor, thus allowing teh surf pointer to be other than NULL, and forcing the method to try and release something that doesnt exist, causing the program to die.


"If you have any questions you may direct
them to that brick wall over there." - South Park


Edited by - IO Fission on October 5, 2000 1:10:30 AM
Shannon Barber
Shannon Barber
without seeing some of your code, it''s hard to say...

use the [ source ] [ / source ] bracket to make it readable
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Eck
Eck
Post some of your code like the destructor/constructors. The line that is creating the surface, etc...

And make sure you know where it is crashing. Log your progress through the code to a file.

Later,
Eck
Houdini
Houdini
Ok, I''m starting to sound like a broken record, but I can''t stress this strongly enough: Allow your app to work in Windowed mode as well as Fullscreen. It takes very little effort and you can actually debug your code line by line and see where the problem is.

If you only work in Fullscreen you''re going to run into this type of problem again and again and it''ll cost you a LOT more development time trying to debug code you can''t see than it would take to implement Windowed mode.

In the meantime, you prolly should paste some code for us to look at...

- Houdini
Houdini
freeman_swe
freeman_swe
I have to agree with Magmai Kai Holmlor and Eck, without source code it´s hard to tell, maybe you could show us the constructor and destructor?
null_pointer
null_pointer
In fullscreen mode, DX will just silently force your app to exit instead of displaying dialog boxes about access violations and whatever else could be going wrong. A very remote possibility is that somehow you''ve installed the reference rasterizer by mistake, or are trying to work with multiple monitors. I think it''s just something with classes...

Can you post some code? Perhaps just the code in the constructor and destructor? Are you actually stepping through the code, or are you just guessing where the error occurs?



- null_pointer
Sabre Multimedia
IO Fission
IO Fission
Sorry, I thought that code would be enough.

        
CSurface
{
private:
LPDDSURFACE7 surf;

public:
CSurface( void ) { surf = NULL; }
~CSurface( void ) { DeleteSurface(); }
void DeleteSurface( void ) { if( surf ) surf->Release(); }
}

I hope that's enough now.

I'm very sure that it is at least something to do with the destructor. When I comment out the call to DeleteSurface() it runs fine. I know that creating the surface and destroying the surface are going alright. I've gone throught the code around it, I know that it is stuffing up as soon as I make a CSurface.

Yes, I should put it in windowed mode. I have been humbled...
Ideas?


IO_FissionSig();

Edited by - IO Fission on October 12, 2000 3:46:18 AM
null_pointer
null_pointer
If you are looking for a "safe" DeleteSurface() function - one that can be called as many times as you want without crashing - then you need to set the surface to NULL after you release it:

if( surf ) surf->Release(); surf = NULL;

That way, the next time and all times thereafter that DeleteSurface is called, surf will be NULL, and Release() won''t be called twice.

As for the reason why DeleteSurface() is being called twice, I don''t know. It depends on the design of your program. You might be making temporary copies somewhere along the line. How are you passing it to functions? Or are you calling DeleteSurface() yourself and letting the destructor be called?

Happy Coding!



- null_pointer
Sabre Multimedia
WhatEver
WhatEver
Just what mr. null_pointer said. You gotta make sure you null those suckin'' pointers after you delete them. I can''t say I haven''t forgotten too .
IO Fission
IO Fission
*embarrased*

I didn''t copy/paste my code to the message here, so I accidentally left out the bit just after the release that says surf = NULL;

I''ve managed to narrow it down somewhat, even though it seems to contradict what I tested a while before.

It definately has something to do with the destructor. If the destructor has no operations (ie {}), the program runs fine, no complaints. When it has {DeleteSurface();}, some wierd stuff happens.

It comes up with an unhandled exception (I think) when I try to use certain surfaces for either blitting or using as a texture (I can set it to do either for blitting to the screen). I used the debugger and found that it was stuffing up when it tried to use surfaces that had a NULL pointer inside the IUnknown class. The create surface function doesn''t fail, but it is able to. I can''t undestrand why. I don''t think there is much more code I have left to check!


IO_FissionSig();
Zipster
Zipster
You might be having scope problem. Post the entire block of code (the message loop according to you), then we can se whats going on. From what i can see, the scope of the class isn't high enough, and the desctructor is being called once the end brace is reached. Try declaring the variable as a global, right under your includes.

As you know, a deconstructor is called when a class goies out of scope, and in your case, surface memory is released and nullified. You said when you remove the deconstructor, it works. Thats because even though the classes default constructor is called, and the class dies, the memory allocated is still allocated, which is why when you access the memory later in the program, it works. In the later case you're losing resources, and in the other case you can't run the program. Try the suggestion and then post the block.

Edited by - Zipster on October 14, 2000 11:06:53 PM
LilBudyWizer
LilBudyWizer
My guess would be that it is calling the constructor and destructor in one line of code because the variable isn''t referanced. Since it may have some side effect such as writing a log record it can''t skip it completely, but it can delete it after the last referance. Beyond that I would say there is an error in the destructor logic.
Keys to success: Ability, ambition and opportunity.

Topic Locked

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

Sign in to reply to this topic.