Bug 13642 – std.container.Array: change of length reallocates without notifying GC

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-10-21T06:10:43Z
Last change time
2018-03-05T17:58:22Z
Assigned to
No Owner
Creator
thedeemon

Comments

Comment #0 by dlang — 2014-10-21T06:10:43Z
The Array.Payload.length setter calls realloc() when length increases, but doesn't call GC.removeRange and GC.addRange. When data in the array contains pointers to some managed objects, GC may collect those objects and now we have dangling pointers in the array, which later causes Access Violations. The following program crashes on 2.066: module main; import std.stdio, std.container.array, core.memory; class C { void hi() { writeln("hi"); } } void main(string[] argv) { Array!C arr; enum N = 10; //arr.reserve(N); // uncomment this and it will work fine arr.length = N; foreach(ref x; arr) x = new C; // create N objects GC.collect(); // do a GC arr[1].hi(); // now this object is dead! }
Comment #1 by safety0ff.bugz — 2014-10-21T08:37:29Z
Right, the realloc in length(size_t) should be replaced with similar code to reserve, i.e.: static if (hasIndirections!T) // use malloc/copy/free along with GC.addRange & GC.removeRange else // use realloc
Comment #2 by github-bugzilla — 2018-03-05T17:58:21Z
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/e837813478298593fdb2799e5af99b40a3ccb7b3 Fix issue 13642 - Change of length reallocates without notifying GC https://github.com/dlang/phobos/commit/997464b4b2a4a0af0fd6eeef1a9b3770c54762b9 Merge pull request #4885 from rjframe/arraymem Fix issue 13642 - Change of length reallocates without notifying GC merged-on-behalf-of: Jack Stouffer <[email protected]>