digitalmars.D.bugs - [Issue 17393] New: AllocatorList leaks memory in "ouroboros mode"
- via Digitalmars-d-bugs (74/74) May 12 2017 https://issues.dlang.org/show_bug.cgi?id=17393
https://issues.dlang.org/show_bug.cgi?id=17393 Issue ID: 17393 Summary: AllocatorList leaks memory in "ouroboros mode" Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: normal Priority: P1 Component: phobos Assignee: nobody puremagic.com Reporter: sludwig outerproduct.org 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. --
May 12 2017