D - missing calls to destructors
- one_mad_alien hotmail.com (100/100) Feb 11 2004 Is this the correct behaviour for dmd 0.79 ?
Is this the correct behaviour for dmd 0.79 ? any class that implements an interface or has a manual constructor does not get its destuctor called on exit as other objects do. example: ------------------------------------------- import std.c.stdio; import object; import std.asserterror; import std.c.windows.com; import std.gc; interface IBar : IUnknown { extern(Windows) void check(); } class CBar : ComObject, IBar { private static int nextId = 0; private static int getId() { return nextId++; } private int id; private int _val; this( int val ) { id = getId(); _val = val; printf( "Bar::Bar(%d):%d\n", id, _val ); } ~this() { printf( "Bar::~Bar(%d):%d\n", id, _val ); } extern(Windows) void check() { printf( "Bar(%d):%d::check()\n", id, _val ); } } class Foo { private static int nextId = 0; private static int getId() { return nextId++; } private int id; private int _val; this( int val ) { id = getId(); _val = val; printf( "Foo::Foo(%d):%d\n", id, _val ); } ~this() { printf( "Foo::~Foo(%d):%d\n", id, _val ); } } class Manual : Foo { this( int val ) { super(val); } new( uint sz ) { void* p; p = std.c.stdlib.malloc(sz); if (!p) { throw new Exception("Out of memory"); } std.gc.addRange(p, p + sz); printf( "Manual::Manual(%p)\n", p ); return p; } delete(void* p) { printf( "Manual::~Manual(%p)\n", p ); if (p){ std.gc.removeRange(p); std.c.stdlib.free(p); } } } int main( char[][] args ) { IBar getIbar() { return new CBar(400); } try { auto Foo f = new Foo( 100 ); Foo fred1 = new Foo( 201 ); Foo fred2 = new Manual( 202 ); CBar b = new CBar( 300 ); IBar c = getIbar(); b.check(); c.check(); } catch ( Exception e ) { printf( "Caught Exception(%.*s)\n", e.toString() ); } catch ( AssertError ae ) { printf( "Caught AssertError(%.*s)\n", ae.toString() ); } catch ( Object o ) { printf( "Caught Object(%.*s)\n", o.toString() ); } return 0; } /* /// this code run on dmd 0.79 outputs Foo::Foo(0):100 Foo::Foo(1):201 Manual::Manual(00840F6C) Foo::Foo(2):202 Bar::Bar(0):300 Bar::Bar(1):400 Bar(0):300::check() Bar(1):400::check() Foo::~Foo(0):100 Foo::~Foo(1):201 */
Feb 11 2004
Can you, and all other posters, convert tabs to spaces before posting code. There's simply no way I'm going to raise the mental effort to try and parse your code, nor the physical effort to reformat it. I would assume that just about everyone else feels the same, hence the lack of response to your post. Any decent IDDE can do this, or you can do it using the untabify.pl script available from http://synsoft.org/perl.html <one_mad_alien hotmail.com> wrote in message news:c0dokp$4gt$1 digitaldaemon.com...Is this the correct behaviour for dmd 0.79 ? any class that implements an interface or has a manual constructor does not get its destuctor called on exit as other objects do. example: ------------------------------------------- import std.c.stdio; import object; import std.asserterror; import std.c.windows.com; import std.gc; interface IBar : IUnknown { extern(Windows) void check(); } class CBar : ComObject, IBar { private static int nextId = 0; private static int getId() { return nextId++; } private int id; private int _val; this( int val ) { id = getId(); _val = val; printf( "Bar::Bar(%d):%d\n", id, _val ); } ~this() { printf( "Bar::~Bar(%d):%d\n", id, _val ); } extern(Windows) void check() { printf( "Bar(%d):%d::check()\n", id, _val ); } } class Foo { private static int nextId = 0; private static int getId() { return nextId++; } private int id; private int _val; this( int val ) { id = getId(); _val = val; printf( "Foo::Foo(%d):%d\n", id, _val ); } ~this() { printf( "Foo::~Foo(%d):%d\n", id, _val ); } } class Manual : Foo { this( int val ) { super(val); } new( uint sz ) { void* p; p = std.c.stdlib.malloc(sz); if (!p) { throw new Exception("Out of memory"); } std.gc.addRange(p, p + sz); printf( "Manual::Manual(%p)\n", p ); return p; } delete(void* p) { printf( "Manual::~Manual(%p)\n", p ); if (p){ std.gc.removeRange(p); std.c.stdlib.free(p); } } } int main( char[][] args ) { IBar getIbar() { return new CBar(400); } try { auto Foo f = new Foo( 100 ); Foo fred1 = new Foo( 201 ); Foo fred2 = new Manual( 202 ); CBar b = new CBar( 300 ); IBar c = getIbar(); b.check(); c.check(); } catch ( Exception e ) { printf( "Caught Exception(%.*s)\n", e.toString() ); } catch ( AssertError ae ) { printf( "Caught AssertError(%.*s)\n", ae.toString() ); } catch ( Object o ) { printf( "Caught Object(%.*s)\n", o.toString() ); } return 0; } /* /// this code run on dmd 0.79 outputs Foo::Foo(0):100 Foo::Foo(1):201 Manual::Manual(00840F6C) Foo::Foo(2):202 Bar::Bar(0):300 Bar::Bar(1):400 Bar(0):300::check() Bar(1):400::check() Foo::~Foo(0):100 Foo::~Foo(1):201 */
Feb 17 2004
Overriding operators new and delete mean that you're in charge of the memory allocation/deallocation for it, not the gc. I don't see any where in your code where fred2 is deleted. <one_mad_alien hotmail.com> wrote in message news:c0dokp$4gt$1 digitaldaemon.com...Is this the correct behaviour for dmd 0.79 ? any class that implements an interface or has a manual constructor does not get its destuctor called on exit as other objects do. example: ------------------------------------------- import std.c.stdio; import object; import std.asserterror; import std.c.windows.com; import std.gc; interface IBar : IUnknown { extern(Windows) void check(); } class CBar : ComObject, IBar { private static int nextId = 0; private static int getId() { return nextId++; } private int id; private int _val; this( int val ) { id = getId(); _val = val; printf( "Bar::Bar(%d):%d\n", id, _val ); } ~this() { printf( "Bar::~Bar(%d):%d\n", id, _val ); } extern(Windows) void check() { printf( "Bar(%d):%d::check()\n", id, _val ); } } class Foo { private static int nextId = 0; private static int getId() { return nextId++; } private int id; private int _val; this( int val ) { id = getId(); _val = val; printf( "Foo::Foo(%d):%d\n", id, _val ); } ~this() { printf( "Foo::~Foo(%d):%d\n", id, _val ); } } class Manual : Foo { this( int val ) { super(val); } new( uint sz ) { void* p; p = std.c.stdlib.malloc(sz); if (!p) { throw new Exception("Out of memory"); } std.gc.addRange(p, p + sz); printf( "Manual::Manual(%p)\n", p ); return p; } delete(void* p) { printf( "Manual::~Manual(%p)\n", p ); if (p){ std.gc.removeRange(p); std.c.stdlib.free(p); } } } int main( char[][] args ) { IBar getIbar() { return new CBar(400); } try { auto Foo f = new Foo( 100 ); Foo fred1 = new Foo( 201 ); Foo fred2 = new Manual( 202 ); CBar b = new CBar( 300 ); IBar c = getIbar(); b.check(); c.check(); } catch ( Exception e ) { printf( "Caught Exception(%.*s)\n", e.toString() ); } catch ( AssertError ae ) { printf( "Caught AssertError(%.*s)\n", ae.toString() ); } catch ( Object o ) { printf( "Caught Object(%.*s)\n", o.toString() ); } return 0; } /* /// this code run on dmd 0.79 outputs Foo::Foo(0):100 Foo::Foo(1):201 Manual::Manual(00840F6C) Foo::Foo(2):202 Bar::Bar(0):300 Bar::Bar(1):400 Bar(0):300::check() Bar(1):400::check() Foo::~Foo(0):100 Foo::~Foo(1):201 */
Jul 19 2004