custom memory management

Simon Bürger" <simon.buerger at rwth-aachen.de> Simon Bürger" <simon.buerger at rwth-aachen.de>
Thu Feb 27 13:46:15 PST 2014


I am trying to implement a structure with value semantics which 
uses an internal buffer. The first approach looks like this:

     struct S
     {
         byte[] buf;

         this(int size) { buf = new byte[size]; }
         this(this) { buf = buf.dup; }
         ~this(this) { delete buf; }
     }

This works fine as long as such an object is allocated on the 
stack (so the destructor is called at the end of the scope). 
However when the destructor is called by the gc, the buffer might 
already be collected, and freeing it a second time is obviously 
invalid.

My second approach was to allocate the buffer outside the 
gc-managed heap, like so:

     this(int size) {
         buf = (cast(byte*)core.stdc.stdlib.malloc(size))[0..size];
     }

     ~this(this) {
         core.stdc.stdlib.free(buf);
     }

Sadly, this is incorrect as well. Because if such an object is 
collected by the gc, but the gc decides not to run the 
destructor, the buffer will never be free'd.

If the gc would either always or never call struct-destructors, 
one of my two solutions would work. But the current situation is 
(in compliance with the language spec), that it is called 
_sometimes_, which breaks both solutions.

One way the first approach could work would be for the destructor 
to check wether it was called by the gc, and skip the 
deallocation in that case. But as far as I know, the gc does not 
provide such a method. It would be trivial to implement, but 
seems kinda hackish.

I know the suggested way in D is to not deallocate the buffer at 
all, but rely on the gc to collect it eventually. But it still 
puzzles me that it seems to be impossible to do. Anybody have an 
idea how I could make it work?

thanks, simon


More information about the Digitalmars-d-learn mailing list