I got your point. Thanks for the reply! Wouldn't it make more sense for GC to ignore second deallocation? If this was the case, data, which is know to become garbage would be deallocated right away. On the other hand, I might as well use std.c.stdlib.realloc for these cases.
On Wed, May 9, 2012 at 8:43 PM, Steven Schveighoffer <[email protected]> wrote: > On Wed, 09 May 2012 12:12:55 -0400, Gor Gyolchanyan > <[email protected]> wrote: > >> I'm not deleting the member. I'm deleting memory, allocated by the member. > > > The member is a struct, so it's fully contained within the class's block. > Therefore, the memory block is a member, even if indirectly so. > > >> If GC deleted it before the object, the same error would appear when I >> forced a GC collection cycle. >> Also, docs clearly say, that I'm free to delete the memory myself. >> This means, that I shouldn't care if a collection cycle went before my >> deletion! > > > Here is how it works. This is not your example, it's an even simpler one. > > Memory block A has a pointer to memory block B. Both are GC allocated. A > is an object with a dtor that calls GC.delete(B). Since A has the only > pointer to B, B is not removed by the GC as long as A is pointed at. > > Now, A is no longer pointed at, and a GC collection runs. > > The GC marks all memory, does not mark A, and therefore, does not mark B, so > now A and B are scheduled for deletion. > > After the mark period, the GC cycles through all deletable (unmarked) memory > blocks, and finds *B first*. Since B has no dtor, it's simply deallocated. > > However, A has a destructor. So first, the runtime runs A.__dtor(), which > *again* deletes B. This is where the failure occurs. > > For this reason, you cannot have a destructor which deletes GC-allocated > memory. This is even in the spec. > > -Steve -- Bye, Gor Gyolchanyan.
