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

Reply via email to