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