Problem in a system of "uncollected' object

D-ratiseur thisoneisinvalid at nowhere.fr
Tue Feb 26 09:37:56 PST 2013


Hello, I'm learning D with a strong Delphi/O.Pascal background. 
As a test I try to implement a system of ownership which 
completelly bypasses the GC.

For the "uncollected object" ancestor, I use the example provided 
in the documentation:


class TUObject: Object
{
     new(size_t sz)
     {
         void* p;

         p = std.c.stdlib.malloc(sz);

         if (!p)
             throw new OutOfMemoryError();

         return p;
     }

     delete(void* p)
     {
         if (p)
         {
             std.c.stdlib.free(p);
         }
     }

     unittest
     {
         auto UnmanagedObj = new TUObject;
         assert( GC.getAttr( &UnmanagedObj ) == 0, "UnmanagedObj 
shouldnt be managed");
         delete UnmanagedObj;
     }
}

Then I have a descendant, it basically illustrates how the owned 
Objects will be destroyed, even if the ownership system is not at 
all implemented:

class TOwned: TUObject
{
     private
     {
         TUObject FOwned;
     }

     public
     {
         this()
         {
             FOwned = new TUObject;
         }

         ~this()
         {
             delete FOwned;
             FOwned = null;
         }
     }

     unittest
     {

         TUObject* Owned = null;

         auto Root = new TOwned;

         assert( GC.getAttr( &Root ) == 0, "Root shouldnt be 
managed");

         Owned = &Root.FOwned;
         delete Root;

         assert(  (*Owned) is null , "dereference of pointer to 
Root.Owned shoud be null" );
         assert(  (Owned) !is null , "pointer to Root.Owned shoud 
look valid" );

     }
}

So far everything works fine but I've found that even if I don't 
delete FOwned in TOwned.~this(), the unittest passes. So now the 
real problem is illustrated in a similar class:

class TOwnedShouldntPass: TUObject
{
     private
     {
         TUObject FOwned;
     }

     public
     {
         this()
         {
             FOwned = new TUObject;
         }

         ~this()
         {
             // FWoned not free
         }
     }

     unittest
     {

         TUObject* Owned = null;

         auto Root = new TOwnedShouldntPass;

         assert( GC.getAttr( &Root ) == 0, "Root shouldnt be 
managed");

         Owned =  &Root.FOwned;
         delete Root;

         assert(  (*Owned) !is null , "dereference of pointer to 
Root.Owned should still be valid" );
         assert(  (Owned) !is null , "pointer to Root.Owned shoud 
look valid" );
     }
}

The first assertion fails, while I would expect "Owned" to be a 
dangling pointer. Basically it should not be null but accessing 
to one of its member would trigger some AV.
Why does the dereference of Owned always equal to null ?
Do I miss a subtility of D pointers/references ?



More information about the Digitalmars-d-learn mailing list