Managing malloced memory

Steven Schveighoffer schveiguy at gmail.com
Tue Oct 12 00:12:37 UTC 2021


On 10/11/21 6:53 AM, anon wrote:
> On Thursday, 7 October 2021 at 11:55:35 UTC, Steven Schveighoffer wrote:
>> The GC is technically not required to free any blocks ever. But in 
>> general, it does.
>>
>> When it does free a struct, as long as you allocated with `new`, it 
>> should call the dtor.
> 
> In practice when I played around with it, destructor always got called 
> by GC. But: https://dlang.org/spec/class.html#destructors says at point 6:
>> The garbage collector is not guaranteed to run the destructor for all 
>> unreferenced objects.
> Is it the same for structs or are these destructors guaranteed to be 
> called? Would it be suitable to clean up tempfiles with GC-managed structs?

It's not guaranteed to run the destructor because it's not guaranteed to 
clean up the memory at all. For sure, it will not clean up the memory 
without first running the destructor (except on process termination, 
which will obviously clean up everything without running destructors).

This is par for the course with GCs, they all have fine print that says 
the destructors (finalizers) may not be called. Most of the time it 
means that the memory will not get cleaned up too. But it's technically 
spec-compliant for the GC to not run the dtor and clean up the memory.

Temp files I would say to ensure they are cleaned up synchronously. 
Though my best practice recommendation is to clean up non-memory 
resources using destructors that will leak if you forget to 
synchronously clean them up.

>> Just FYI, you should reply to the posts that you quote, or at least 
>> copy the "X Y wrote" line so people understand the thread.
> 
> Alright. If I want to reply to multiple people, should I post twice or 
> quote both in the same post?

You can do it either way. It just looked from your message like I was 
saying the things that H.S. Teoh did.

For sure, if you want a response from someone, it's good to reply 
directly to their post.

>> The destructor is called once per copy. This is why disabling copy 
>> prevents double freeing.
>>
>> There are cases where the compiler avoids calling the destructor 
>> because the instance is moved. Such as returning a newly constructed 
>> item (typically referred to as an "rvalue"), or passing a newly 
>> constructed item into a parameter. The parameter will be destroyed, 
>> but the call-site constructed item will not.
>>

> Is there any reference for exactly how these rules apply, or is this 
> implementation defined? The 
> [specification](https://dlang.org/spec/struct.html#struct-destructor) 
> says that destructors are called when objects go out of scope. Your 
> examples seem to suggest that this is untrue in some cases.

A struct on the heap doesn't go out of scope after the stack frame, 
since it's still on the heap.

Unfortunately, the spec is maintained over history, and historically, 
struct destructors were not run by the GC even when the memory was 
cleaned up. So this terminology is focused on structs that were mostly 
only functional on the stack.

-Steve


More information about the Digitalmars-d-learn mailing list