Surprising behaviour of std.experimental.allocator
ag0aep6g
anonymous at example.com
Sat Dec 26 19:36:24 UTC 2020
On 26.12.20 13:59, ag0aep6g wrote:
> Looks like a pretty nasty bug somewhere in std.experimental.allocator or
> (less likely) the GC. Further reduced code:
>
> ----
[...]
> ----
>
> Apparently, something calls deallocateAll on a Mallocator instance after
> the memory of that instance has been recycled by the GC. Maybe
> allocatorObject or AllocatorList keep a reference to GC memory out of
> sight of the GC.
I've looked into it some more, and as far as I can tell this is what
happens:
1) allocatorObject puts the AllocatorList instance into malloced memory.
2) The AllocatorList puts the Mallocator instance into GC memory,
because its default BookkeepingAllocator is GCAllocator.
3) The GC recycles the memory of the Mallocator instance, because it's
only reachable via the malloced AllocatorList instance and malloced
memory isn't scanned by default.
4) Hell breaks loose because that recycled memory was not actually garbage.
I'm not so sure anymore if this qualifies as a bug in
std.experimental.allocator. Maybe AllocatorList should be registering
its GC allocations as roots?
As a solution/workaround, you can use NullAllocator for AllocatorList's
BookkeepingAllocator:
----
import std.experimental.allocator.building_blocks.null_allocator :
NullAllocator;
alias Alloc1 = FallbackAllocator!(
AllocatorList!(n => Region!Mallocator(1024*1024), NullAllocator),
Mallocator);
----
More information about the Digitalmars-d-learn
mailing list