Accessing memory after destroy

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Tue Aug 1 07:31:10 PDT 2017


On 7/30/17 9:17 AM, Petar Kirov [ZombineDev] wrote:
> On Sunday, 30 July 2017 at 07:45:27 UTC, Johan Engelen wrote:
>> On Saturday, 29 July 2017 at 23:09:38 UTC, Jonathan M Davis wrote:
>>>>
>>>> [1] https://dlang.org/spec/class.html#deallocators
>>>
>>> If destroy has been called on a class object, then it is a bug to 
>>> access it at any point after that (IIRC, the expectation is that it 
>>> will blow up in your face, because the vtable is gone - TDPL talks 
>>> about this, I believe, but I don't know where my copy is at the 
>>> moment, so I can't check). That being said, the memory is still 
>>> valid. And as Moritz pointed out, if the memory is accessible, the GC 
>>> won't free it. So, it's a bug to access the object, but it should be 
>>> memory safe to do so.
>>
>> If this is the case, then we really need to improve and pin-down the 
>> spec on this point.
>>
>> So `destroy` only calls the destructor and puts the object in 
>> `T.initializer` (non-constructed) state, and is otherwise not related 
>> to memory deallocation.
>> May the destructor be called again when the GC collects the memory?
>> Why is the object put in `T.initializer` state?
> 
> rt_finalize2 zeroes the vptr out after assigning typeid(T).initializer, 
> so calling the destructor more than once is not possible, unless someone 
> manually saves the vptr and assigns it back to the object after the call 
> to destroy / rt_finalize.

Yes, this is on purpose. It's the way the runtime knows it has already 
been run. In fact, destroy used to NOT do this, and that caused problems.

A class instance is not usable after calling destroy. It is not intended 
to be usable, because classes require a constructor call to be valid, 
and there's no way to guarantee you can do this with destroy.

Structs are different.

>> To make sure: My question is from a spec point of view. Not about what 
>> currently happens and what is "OK" with the current implementation.
> 
> I guess the spec needs to be updated to state explicitly that a class 
> destructor is called only once, if that's not already the case.

I thought this was in the spec, but I can't find it. This is definitely 
the case.

-Steve


More information about the Digitalmars-d mailing list