import std;
import core.memory;
struct B
{
int[] b;
~this ()
{
b[0]++;
writeln(b[0]);
}
}
void main()
{
B[] b_list;
foreach(idx; 0 ..100)
b_list ~= B([0]);
b_list.length = 0;
GC.collect();
}
---------------------------------------------------------
One would assume that B.b[0] would always be 0 before destructor runs. But if b_list is ever relocated while trying to expand its size, GC will finalize objects while trying to collect the old memory for b_list and cause all objects in b_list to be finalized multiple times.
Comment #1 by omerfirmak — 2021-11-12T10:37:47Z
Previous sample code was missing some parts;
--------------------
import std;
import core.memory;
struct B
{
int[] b;
~this ()
{
b[0]++;
writeln(b[0]);
}
@disable this(this);
this (ref B rhs) @trusted nothrow pure
{
this.b = rhs.b.dup;
}
}
void main()
{
B[] b_list;
foreach(idx; 0 ..100)
b_list ~= B([0]);
b_list.length = 0;
GC.collect();
}
Comment #2 by robert.schadek — 2024-12-07T13:41:28Z