On Monday, 20 September 2021 at 18:13:53 UTC, Steven Schveighoffer wrote:
> On 9/20/21 10:22 AM, Tejas wrote:
> In case you still want to delete stuff deterministically despite what Steve said, I suggest you make your struct
a reference and use core.memory.__delete
(not recommended to use this carelessly, btw)
Do not call __delete
here, use destroy
. __delete
will attempt to deallocate the block, which likely will fail since the key comes before the value, and GC.free on an interior pointer (I think) fails.
But if it succeeded, it would not be good. This leaves a dangling pointer inside the AA. Rehashing the AA likely would result in a memory corruption.
If you use destroy, the destructor will be called by the GC as well, but a struct should properly handle destroying the .init value.
-Steve
It doesn't succeed when object is stack allocated, otherwise it works; that's why I suggested changing S
to S*
.
As for why I didn't use destroy
, I assumed OP wanted to free the memory. If they just want the destructor to run, then destroy
is better(and safer).
(Also, hashOf
seems to work just fine even after using __delete
, not that it means using __delete
should ever be recommended over using destroy
)
import std.stdio;
import core.memory:__delete;
struct S
{
int a;
this(int param){
a = param;
}
~this()
{
writeln("S(",a,") is being destructed");
}
}
void absoluteRemove(AA, keyType)(AA assArray, keyType key){
//assArray.remove(key);
__delete(assArray[key]);
}
void main()
{
S*[int] aa;
aa[1] = new S(5);
absoluteRemove(aa, 1);
writeln(aa.hashOf);
aa[2] = new S(10);
writeln(aa.hashOf);
absoluteRemove(aa, 2);
writeln(aa.hashOf);
writeln("Why no dtor call on remove?");
}
Output:
S(5) is being destructed
2451737883
5104465521
S(10) is being destructed
5378492086
Why no dtor call on remove?