Dynamic arrays, emplace and GC
Claude via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jul 5 03:04:05 PDT 2016
Hello,
I've been working on some kind of allocator using a dynamic array
as a memory pool. I used emplace to allocate class instances
within that array, and I was surprised to see I had to use
GC.addRange() to avoid the GC to destroy stuff referenced in that
array.
Here's a chunk of code[1]:
struct Pool(T)
{
public:
T alloc(Args...)(Args args)
{
mData.length++;
import core.memory : GC;
//GC.addRange(mData[$ - 1].data.ptr, mData[$ -
1].data.length);
import std.conv : emplace;
auto t = emplace!T(mData[$ - 1].data, args);
return t;
}
private:
struct Storage
{
ubyte[__traits(classInstanceSize, T)] data;
}
Storage[] mData;
}
class Foo
{
this(int a)
{
aa = a;
}
~this()
{
import std.stdio; writefln("DTOR");
aa = 0;
}
int aa;
}
class Blob
{
this(int b)
{
foo = new Foo(b);
}
Foo foo;
}
void main()
{
Pool!Blob pool;
Blob blob;
foreach(a; 0 .. 10000)
{
blob = pool.alloc(6);
}
while(true){}
import std.stdio; writefln("END");
}
Basically Blob instances are allocated in the array using
emplace. And Blob creates references to Foo. If I comment out
GC.addRange(), I see that Foo destructor is called by the GC[2].
If I leave it uncommented, the GC leaves the array alone.
So here's my question: Is it normal???
I thought that allocating memory in a dynamic array using
"mData.length++;" was GC-compliant (unlike
core.stdc.stdlib.malloc()), and I did not have to explictly use
GC.addRange().
[1] I left out alignment management code. It's not the issue here.
[2] I used the helpful destructor tracker function of p0nce
there: https://p0nce.github.io/d-idioms/#GC-proof-resource-class
More information about the Digitalmars-d-learn
mailing list