Bug 15637 – Region allocator assert failure when expanding the last allocation
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2016-02-01T22:22:16Z
Last change time
2017-12-18T22:56:35Z
Assigned to
Andrei Alexandrescu
Creator
mark
Comments
Comment #0 by mark — 2016-02-01T22:22:16Z
The following code crashes with an assert failure at std/experimental/allocator/building_blocks/region.d:235 on 64-bit Linux and 32-/64-bit Windows, using DMD version 2.070.0:
import std.experimental.allocator;
import std.experimental.allocator.building_blocks;
void main(string[] args) {
ubyte[1024] memory;
auto alloc = Region!NullAllocator(memory);
auto result = alloc.allocate(20);
alloc.expand(result, 20);
}
The region allocator's expand function doesn't take into account any existing alignment padding when calculating the new allocation size, which pushes the _current pointer past the expected value.
This could probably be fixed with something like:
static if (growDownwards == No.growDownwards)
bool expand(ref void[] b, size_t delta)
{
assert(owns(b) == Ternary.yes || b.ptr is null);
assert(b.ptr + b.length <= _current || b.ptr is null);
if (!b.ptr)
{
b = allocate(delta);
return b.length == delta;
}
auto newLength = b.length + delta;
if (_current < b.ptr + b.length + alignment)
{
immutable currentAllocSize = this.goodAllocSize(b.length);
immutable requiredAllocSize = this.goodAllocSize(newLength);
immutable allocDelta = requiredAllocSize - currentAllocSize;
// This was the last allocation! Allocate some more and we're done.
if (currentAllocSize == requiredAllocSize
|| allocate(allocDelta).length == allocDelta)
{
b = b.ptr[0 .. newLength];
assert(_current < b.ptr + b.length + alignment);
return true;
}
}
return false;
}
Comment #1 by github-bugzilla — 2017-11-13T18:22:56Z