January 15, 2021
https://issues.dlang.org/show_bug.cgi?id=21550

          Issue ID: 21550
           Summary: core.memory.__delete does not actually work
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: druntime
          Assignee: nobody@puremagic.com
          Reporter: destructionator@gmail.com

I just had a user come to me perplexed that a big array wasn't being freed. Since they on 32 bit working with large images, I figured it was a false pointer (and no, the semi-precise GC doesn't help either - we tried - cuz stack pointers can still pin it).

But that's OK, I said, there's a public, just undocumented, clear function you can use which frees it manually.

The memory leak persisted.

I looked into it and, nope, my library frees everything it mallocs, and the clear function calls __delete, just like the documentation says to do ever since the delete keyword was deprecated. But indeed, the memory leak persists.

Replacing it with the original delete keyword works fine.

After looking closer, I see the problem: https://dlang.org/phobos/core_memory.html#.__delete is broken.


See, the original _d_delarrayT function does this: GC.free(info.base);

The new __delete implementation does this: GC.free(cast(void*) x.ptr).

The difference: http://dpldocs.info/experimental-docs/core.memory.GC.free.html

"if p points to the interior of a memory block [...] no action will be taken."

An array is not actually necessarily at the start of a block. Making __delete (or a direct call to GC.free for that matter) a silent no-op.

--