digitalmars.D.learn - What on earth is happening? Mutual dtors
- Jarrett Billingsley (73/73) Aug 20 2005 Out of curiosity, I wrote this:
- xs0 (7/99) Aug 21 2005 Hi,
- Jarrett Billingsley (27/32) Aug 21 2005 But "delete a" in main() will not set the 'a' member of 'B' to null; onl...
- Bruno Medeiros (8/11) Aug 25 2005 I suppose calling delete twice on the same object is illegal and causes
Out of curiosity, I wrote this: import std.stdio; class A { B b; ~this() { delete b; writefln("a dtor: ",cast(void*)b); } } class B { A a; ~this() { delete a; writefln("b dtor: ",cast(void*)a); } } void main() { A a=new A; B b=new B; a.b=b; b.a=a; delete a; fflush(stdout); } I expected it to get caught in an infinite loop between the two dtors, but surprisingly, all that is printed is a dtor: 0 b dtor: 0 But then, the program hangs in gc_term(). What is happening here? Why don't the objects get caught in an infinite loop between their dtors? And if they're no longer pointing to one another after they are dtor'ed (but most likely not GCed), why does gc_term() hang? On a side note, this code does not hang the gc_term(): import std.stdio; class A { B b; bit isDeleting; ~this() { isDeleting=1; if(!b.isDeleting) delete b; } } class B { A a; bit isDeleting; ~this() { isDeleting=1; if(!a.isDeleting) delete a; } } void main() { A a=new A; B b=new B; a.b=b; b.a=a; delete a; } Which is odd. For some reason, mutually calling dtors doesn't cause the dtors to stick in an infinite loop, but it causes gc_term() to. But even though the classes have the same structure in this example, and their pointers to one another have the same values (null), gc_term() doesn't hang.
Aug 20 2005
Hi, "delete a;" will also set a to null, so you can't delete it twice, hence no loop.. I'm not sure about gc_term, though, but I think it's first a bug that you try to delete a twice (once from main, once from b)... xs0 Jarrett Billingsley wrote:Out of curiosity, I wrote this: import std.stdio; class A { B b; ~this() { delete b; writefln("a dtor: ",cast(void*)b); } } class B { A a; ~this() { delete a; writefln("b dtor: ",cast(void*)a); } } void main() { A a=new A; B b=new B; a.b=b; b.a=a; delete a; fflush(stdout); } I expected it to get caught in an infinite loop between the two dtors, but surprisingly, all that is printed is a dtor: 0 b dtor: 0 But then, the program hangs in gc_term(). What is happening here? Why don't the objects get caught in an infinite loop between their dtors? And if they're no longer pointing to one another after they are dtor'ed (but most likely not GCed), why does gc_term() hang? On a side note, this code does not hang the gc_term(): import std.stdio; class A { B b; bit isDeleting; ~this() { isDeleting=1; if(!b.isDeleting) delete b; } } class B { A a; bit isDeleting; ~this() { isDeleting=1; if(!a.isDeleting) delete a; } } void main() { A a=new A; B b=new B; a.b=b; b.a=a; delete a; } Which is odd. For some reason, mutually calling dtors doesn't cause the dtors to stick in an infinite loop, but it causes gc_term() to. But even though the classes have the same structure in this example, and their pointers to one another have the same values (null), gc_term() doesn't hang.
Aug 21 2005
"xs0" <xs0 xs0.com> wrote in message news:de9c60$2tpq$1 digitaldaemon.com...Hi, "delete a;" will also set a to null, so you can't delete it twice, hence no loop.. I'm not sure about gc_term, though, but I think it's first a bug that you try to delete a twice (once from main, once from b)...But "delete a" in main() will not set the 'a' member of 'B' to null; only the reference to 'a' in main() gets nullified. Meaning that you can call delete twice on 'a', although the second time, it has already been deleted and is still sitting in memory, not yet GCed. In fact, here's another example that causes gc_term() to hang. import std.stdio; class A { ~this() { writefln("a dtor"); } } void main() { A a=new A; A a2=a; delete a; writefln("a: ",cast(void*)a); writefln("a2: ",cast(void*)a2); delete a2; writefln("a2: ",cast(void*)a2); fflush(stdout); } It seems that calling delete on an object twice (though it should really never happen) makes gc_term() hang. I don't know why.
Aug 21 2005
Jarrett Billingsley wrote: >It seems that calling delete on an object twice (though it should really never happen) makes gc_term() hang. I don't know why.I suppose calling delete twice on the same object is illegal and causes undefined and incorrect behaviour (same as calling free() twice on a malloc'ed block). -- Bruno Medeiros Computer Science/Engineering student
Aug 25 2005