Question to GC experts: NO_SCAN for a part of the block

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Jun 5 06:11:25 PDT 2017


On 6/4/17 5:57 AM, Stanislav Blinov wrote:
> On Sunday, 4 June 2017 at 09:38:45 UTC, ag0aep6g wrote:
>
>>> Should this work, and if not, why?
>>
>> As far as I can tell, the `addRange` call works correctly, but maybe
>> too well in a sense. It keeps the `new`ed `C`s alive as long as
>> `arrays3.Cs` has pointers to them. And `arrays3.Cs` has those pointers
>> until the very end.
>
> Yeah, after playing around with the code a bit, shuffling the calls,
> making new allocations, etc., I saw those dtors indeed being run. I was
> just expecting the behavior to be the same as for normal 'new'ed arrays,
> but I guess there are nuances.
>
>> If you add `GC.removeRange(arrays3.Cs.ptr);` at the of `main`, the
>> dtors show up.
>
> Yeah, well, calling it manually sort of defeats the purpose :)

adding a range marks it as having pointers to scan, AND stores a 
reference to that array, so it won't be GC collected (nor will anything 
it points to). The intention is for it to be used on non-GC memory, like 
C malloc'd memory, where it doesn't matter that the GC is pointing at it.

I would say that you are better off allocating 2 arrays -- one with 
NO_SCAN where you put your non-pointer-containing data, and one without 
the flag to put your other data. This is similar to your "selective" 
function, but instead of allocating 1 array, with a tuple of slices into 
it, just allocate 2 arrays and return the tuple of those 2 arrays.

In my dcollections library, the allocator I use uses malloc for 
non-pointer containing arrays, and GC for everything that could contain 
pointers, and then divvy up the array into the exact sizes I want. Works 
quite well, but the dtor of the container needs to deallocate the 
malloc'd one.

-Steve


More information about the Digitalmars-d mailing list