TDPL: Manual invocation of destructor

Steven Schveighoffer schveiguy at yahoo.com
Tue Aug 10 05:25:00 PDT 2010


On Mon, 09 Aug 2010 20:07:28 -0400, Andrej Mitrovic  
<andrej.mitrovich at gmail.com> wrote:

> I don't have a lot of experience in this field, but my guess is people  
> want
> to help out the GC be more efficient in some regard.
>
> "Hey, GC! I know you take the trash out every day, but I just want to let
> you know that I've cleaned up my room and there's a whole bag o' dirt in
> here ready to be thrown out that you should know about. See ya later!"
>
> My assumption is that the programmer probably knows when and how he uses
> memory more so than the GC itself. So my thinking is some kind of hybrid
> approach would be a good choice between safety and performance here. But
> correct me if I'm wrong, I'm walking in the dark really..
>

That is delete.  Here is the problem:

class C {
int x;
}

void main()
{
   auto c = new C;
   c.x = 1;
   auto c2 = c;
   delete c;
   assert(c is null);
   assert(c2 !is null);
   c2.x = 5; // oops!  I just wrote to unallocated memory.
   auto c3 = new C; // might occupy space just freed
   c2.x = 5; // double oops! I may have just overwritten c3
}

compare this to clear.  If clear leaves the memory around until there are  
no references, then referring to that memory does not corrupt other  
unrelated parts of the code.  Memory corruption is the granddaddy of all  
horrible bugs, because the cause is usually a) long gone by the time you  
see any symptoms, b) can be completely decoupled from the symptom, and c)  
can cause *random* symptoms.  If D can avoid memory corruption, and it  
costs very little, it should do so.

The thing is, even with clear, the above code is undefined -- a cleared  
object is in no state to be used.  But the difference between delete and  
clear is -- delete ensures the reference you delete will cause an  
immediate error on use, but does nothing to prevent memory corruption to  
all the other references to the same memory.  Clear does the same for the  
reference you clear, but also prevents memory corruption for all the other  
references to the same memory.  So even though you are in undefined  
territory, the runtime makes a best effort to avoid you cutting off your  
head.  The error may still be silent, but it's not deadly.

It might even be a good idea to zero out the vtable to cause a loud error  
on the next dynamic cast or virtual function call :)

-Steve


More information about the Digitalmars-d mailing list