www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - The delete that never ends the program

reply clayasaurus <clayasaurus_member pathlink.com> writes:
hello, i'm having the following problem. 

My problem is that after I call 'delete' my program never ends and i have to hit
'ctrl-z' to stop it. If i get rid of the delete, my program exits fine. 

i have a class with a destructor like this

~this
{
delete myClass; // this doesn't stop program from exiting
delete myClass2; // this does <-- the one that stops it from ending
}

they are also both the same class type (cClass) 

anyone have any idea what could be up with this?
May 21 2004
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
clayasaurus schrieb:

 hello, i'm having the following problem. 
 
 My problem is that after I call 'delete' my program never ends and i have to
hit
 'ctrl-z' to stop it. If i get rid of the delete, my program exits fine. 

Hmmm... the right thing would be to find out a problematic line with a debugger. Microsoft's debugger work, and you may also try OpenWatcom, if you don't have the Symantec or DigitalMars compiler.
 i have a class with a destructor like this
 
 ~this
 {
 delete myClass; // this doesn't stop program from exiting
 delete myClass2; // this does <-- the one that stops it from ending
 }
 
 they are also both the same class type (cClass) 
 
 anyone have any idea what could be up with this?

Nice. Any shared resources? You could post up the implementation of the distructor cClass, or you could e-mail a stripped-down example to me to examine. -eye/PhotoAllergicCrew
May 22 2004
parent reply clayasaurus <clayasaurus_member pathlink.com> writes:
In article <c8ndfa$haf$1 digitaldaemon.com>, Ilya Minkov says...
clayasaurus schrieb:

 hello, i'm having the following problem. 
 
 My problem is that after I call 'delete' my program never ends and i have to
hit
 'ctrl-z' to stop it. If i get rid of the delete, my program exits fine. 

Nice. Any shared resources? You could post up the implementation of the distructor cClass, or you could e-mail a stripped-down example to me to examine.

hrm... Ok. I made a stripped down example program. i'll add an attachment too. import std.math; import std.stream; class cVector3 // minimal illustration class { public: this() // this can be removed if wish { m_x = 0.0; m_y = 1.0; m_z = 2.0; } private: float m_x, m_y, m_z; } class c3Drectangle // minimal illustration class { public: this() // public function data { m_vPosition = new cVector3(); // allocate data } ~this() { delete m_vPosition; // for some reason this will crash it } void position(cVector3 pos){m_vPosition = pos;} private: cVector3 m_vPosition; // size and position for easy manipulation } class cPlayer // minimal illustration class { public: this() { m_vPosition = new cVector3(); // Init the position to zero m_boundingBox = new c3Drectangle(); } ~this() { delete m_vPosition; delete m_boundingBox; } void update(float eTime) { m_boundingBox.position(m_vPosition); // set position of bounding box to player position } private: cVector3 m_vPosition; c3Drectangle m_boundingBox; } class cEngine { public: this() // default constructer { m_player = new cPlayer(); // player class } ~this() { delete m_player; } void run() // run the engine { m_player.update(1); } private: // my "globals" for my engine cPlayer m_player; // player class } int main(char[][] argv) { // start the engine and allocate all the memory cEngine engine = new cEngine(); // run the engine until the user quits engine.run(); printf("shutting down...\n"); // shutdown the engine and free all its memory delete engine; printf("ok, it should be done by now...\n"); return 0; }
May 22 2004
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Trying a few things.

(1) cEngine does not play any role. Eliminated.
(2) the cVector3 gets constructed twice, but the destructor is called 
only once.
(3) the line, which you marked as "// for some reason this will crash 
it" never results in a destructor call as it should, though the 
execution definately passes the line.

I might try some assembly-level debugging, though i doubt my skill.

For now, i send out the current source which exposes the same bug. I did 
not succeed in reducing it much further.

.... clack clack clack i think i found the bug in your/our source!

The deciding line should be this one:

player.update(1);
-->
m_boundingBox.position(m_vPosition)
-->
void position(cVector3 pos){m_vPosition = pos;}

The last one is particularly evil. It does the following:
- c3DRectangle.m_vPosition first contains a reference fresh cVector3. 
This cVector 3 gets "leaked", that is you loose all references to it and 
it's the domain of Garbage Collector.
- c3DRectangle.m_vPosition gets reassigned to another cVector which was 
originally in cPlayer.m_vPosition. Thus these 2 places get linked to the 
same value.

Then you manually erase the same vector twice through 2 references, and 
first time it works right, second time it seems to work but screws up 
the runtime or the memory manager, which hangs afterwards. :/ Which is 
not good by itself i'd say.

Obvious solution: cVector should be a struct.
You should excercise some Java self-torturing to learn how to deal with 
reference objects without cutting your fingers. Read on copy-on-write 
convention in the D manual.

I find your classes extremely hard to read. What's up? I think you have 
to many meaningless symbols in identifiers.

BTW, what are you trying to write? May it make sense that we sort-of 
team up?

-eye
May 22 2004
parent clayasaurus <clayasaurus yahoo.com> writes:
Ilya Minkov wrote:
 Trying a few things.
 
 (1) cEngine does not play any role. Eliminated.
 (2) the cVector3 gets constructed twice, but the destructor is called 
 only once.
 (3) the line, which you marked as "// for some reason this will crash 
 it" never results in a destructor call as it should, though the 
 execution definately passes the line.
 
 I might try some assembly-level debugging, though i doubt my skill.
 
 For now, i send out the current source which exposes the same bug. I did 
 not succeed in reducing it much further.
 
 .... clack clack clack i think i found the bug in your/our source!
 
 The deciding line should be this one:
 
 player.update(1);
 -->
 m_boundingBox.position(m_vPosition)
 -->
 void position(cVector3 pos){m_vPosition = pos;}
 
 The last one is particularly evil. It does the following:
 - c3DRectangle.m_vPosition first contains a reference fresh cVector3. 
 This cVector 3 gets "leaked", that is you loose all references to it and 
 it's the domain of Garbage Collector.
 - c3DRectangle.m_vPosition gets reassigned to another cVector which was 
 originally in cPlayer.m_vPosition. Thus these 2 places get linked to the 
 same value.
 
 Then you manually erase the same vector twice through 2 references, and 
 first time it works right, second time it seems to work but screws up 
 the runtime or the memory manager, which hangs afterwards. :/ Which is 
 not good by itself i'd say.
 
 Obvious solution: cVector should be a struct.

Ok, well that solution might not be so bad. I'd have to convert a couple member functions into functions that take structs as parameters though. But I like to be consistent, and the question is, if I convert the vector class into a struct, then why not convert all my classes into structs? If I might have the same types of problems.
 You should excercise some Java self-torturing to learn how to deal with 
 reference objects without cutting your fingers. Read on copy-on-write 
 convention in the D manual.

Ahh, java. Well, I'm not particulary motivated to learn java quite yet, unless you think I'd help me a lot. I'm reading the copy-on-write section of the D manual, and I still don't completely "get it" yet. All I can see is that for the first time in the loop you need to make a new copy of an array and then swip-swap them back and forth so that arrays you pass into functions don't become modified.
 I find your classes extremely hard to read. What's up? I think you have 
 to many meaningless symbols in identifiers.

Ok, well I'm coming from c++ where stucts and classes are the same thing. But I'll explain the symbols... cClass // the c tells me it is a class, maybe useless, but i find it handy when declaring cPlayer player = new cPlayer(); I could use Player player = new Player(); but starting a class with capitols seems weird to me. I can't do player player = player; so the c allows me to use generic names for my classes. cVector3 // the 3 tells me that it has x, y, and z. maybe i'll have a cVector2 or cVector4 in the future for some random reason. m_memberVariable; // i put m's in front of all my member variables so it is easy to distinguish between member variables and other variables. It also allows me to use something like this for a member function member_function(char[] window) { m_window = window; } m_vVector; // helps me distinguish vectors from other data types. I use vectors a lot and it is easy for me to spot them this way.
 BTW, what are you trying to write? 

I'm trying to write an easy to use 3D game programming library and level editor to go along with it. I originally started writing the project in C++, but D seems like a better language with great potential so I converted. Right now all I have is a textured box in a 3d world that the player can jump around on. The first goal of mine is to create a world out of simple shapes (boxes first) http://claytek.sourceforge.net/ http://www.dsource.org/forums/viewtopic.php?t=156&sid=6a4c8a3a8186caa3f03f1e28c40e7724 If I can, I'll move the whole operation over to dsource.org/ , as that seems like a better place to be for D programming.
 May it make sense that we sort-of team up?

Sure, if you want to. I need all the help with my code I can get :) you can access the code through cvs via the commands cvs -d:pserver:anonymous cvs.sourceforge.net:/cvsroot/claytek login hit enter, no password cvs -z3 -d:pserver:anonymous cvs.sourceforge.net:/cvsroot/claytek co ClayTek-0.0.1 cvs -z3 -d:pserver:anonymous cvs.sourceforge.net:/cvsroot/claytek co libs command Assuming you have dmd and gcc and SDL and OpenGL installed and you have the SDL and OpenGL D interface files found in the libs dir/ in dmd/src/phobos, all you have to do is type 'make',dmd -c test.d, and pico the Makefile to see how to build it all together with all the libraries and everything.
May 23 2004