Bug 17393 – AllocatorList leaks memory in "ouroboros mode"
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2017-05-12T11:34:24Z
Last change time
2017-11-30T21:39:38Z
Assigned to
No Owner
Creator
Sönke Ludwig
Comments
Comment #0 by sludwig — 2017-05-12T11:34:24Z
The following bails out at the last assertion because there is still a DummyAllocator with allocated memory left over:
---
import std.experimental.allocator;
import std.experimental.allocator.mallocator;
import std.experimental.allocator.building_blocks.allocator_list;
import std.experimental.allocator.building_blocks.region;
import std.experimental.allocator.building_blocks.null_allocator;
import std.algorithm;
// simple region allocator that keeps track of the number of active references
struct DummyAllocator {
import std.typecons : Ternary;
static int cnt;
void[] mem;
size_t ptr;
enum alignment = ulong.alignof;
this(size_t sz) { mem = new void[](sz); cnt++; }
this(this) { if (mem.ptr) cnt++; }
~this() { if (mem.ptr) cnt--; }
Ternary owns(void[] slc)
const {
return slc.ptr >= mem.ptr && slc.ptr + slc.length <= mem.ptr + mem.length ? Ternary.yes : Ternary.no;
}
void[] allocate(size_t n)
{
if (!mem.ptr) {
mem = new void[](1024*1024);
cnt++;
}
if (mem.length - ptr < n) return null;
auto ret = mem[ptr .. ptr + n];
ptr += n;
return ret;
}
bool deallocateAll()
{
if (mem.ptr) {
ptr = 0;
delete mem;
cnt--;
}
return true;
}
}
void main()
{
assert(DummyAllocator.cnt == 0);
{
auto a = AllocatorList!(n => DummyAllocator(max(n, 1024*1024)), NullAllocator).init;
a.allocate(1000);
a.deallocateAll();
}
assert(DummyAllocator.cnt == 0);
}
---
The deallocateAll() call in particular doesn't get forwarded to DummyAllocator and its destructor isn't called either. If NullAllocator is exchanged for Mallocator, this issue doesn't show up.
Comment #1 by alex.jercaianu — 2017-11-30T21:39:38Z