February 26, 2013 Problem in a system of "uncollected' object | ||||
|---|---|---|---|---|
| ||||
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 ?
| ||||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply