digitalmars.D.bugs - [Issue 15790] New: The GC frees managed members made w/
- via Digitalmars-d-bugs (57/57) Mar 11 2016 https://issues.dlang.org/show_bug.cgi?id=15790
https://issues.dlang.org/show_bug.cgi?id=15790 Issue ID: 15790 Summary: The GC frees managed members made w/ allocator.make, causing memory corruption Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: phobos Assignee: nobody puremagic.com Reporter: b2.temp gmx.com The managed members of an aggregate instanciated with std.experimental.allocator can be freed during a GC pass, and even if the allocator used is not GCAllocator. The following program illustrates the issue: import core.memory; import std.experimental.allocator.mallocator; import std.experimental.allocator.common; enum fill = "azertyuiopqsdfghjklm"; auto make(T, Allocator, A...)(auto ref Allocator alloc, auto ref A args) { import std.algorithm : max; import std.conv : emplace; auto m = alloc.allocate(max(stateSize!T, 1)); version(none) GC.addRange(m.ptr, m.length); // activate this to fix the error if (!m.ptr) return null; scope(failure) alloc.deallocate(m); static if (is(T == class)) return emplace!T(m, args); else return emplace(cast(T*) m.ptr, args); } struct Node { this(string c){content = c;} string content; Node*[] nodes; } void main() { Node* root = make!Node(Mallocator.instance, fill); foreach(immutable i; 0 .. 10000) { root.nodes ~= make!Node(Mallocator.instance, fill); foreach(immutable j; 0 .. 100) root.nodes[i].nodes ~= make!Node(Mallocator.instance, fill); } assert(root.content == fill); foreach(immutable i; 0 .. root.nodes.length) { assert(root.nodes[i].content == fill); foreach(immutable j; 0 .. root.nodes[i].nodes.length) assert(root.nodes[i].nodes[j].content == fill); } }
Mar 11 2016