Bug 15721 – free error when calling Mallocator.dispose on interfaces
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-02-25T10:29:33Z
Last change time
2020-03-21T03:56:37Z
Assigned to
No Owner
Creator
joeyemmons
Comments
Comment #0 by joeyemmons — 2016-02-25T10:29:33Z
Seems calling dispose on an interface does not work. The following will cause free to fail:
// someOutputRange is a ubyte[] output range of type O
auto malloc = Mallocator.instance;
OutputRange!(ubyte[]) range;
range = malloc.make!(OutputRangeObject!(O, ubyte[]))(someOutputRange);
// do some stuff...
malloc.dispose(range);
It fails because typeid on interfaces is wonky, who thought that was a good idea...
It can be fixed by changing to:
malloc.dispose(cast(Object)range);
But honestly it should not be necessary and will 100% trip people up.
Comment #1 by b2.temp — 2016-02-26T05:43:04Z
GCAllocator is supported but Mallocator produces a free error:
import std.experimental.allocator.mallocator;
import std.experimental.allocator.gc_allocator;
import std.experimental.allocator;
interface Foo {}
class Bar: Foo {}
void main()
{
GCAllocator.instance.dispose(cast(Foo) GCAllocator.instance.make!Bar);
// comment the following line: OK
Mallocator.instance.dispose(cast(Foo) Mallocator.instance.make!Bar);
}
Comment #2 by b2.temp — 2016-02-26T05:52:59Z
I think this is safe to change dispose to:
void dispose(A, T)(auto ref A alloc, T p)
if (is(T == class) || is(T == interface))
{
if (!p) return;
auto support = (cast(void*) cast(Object) p)[0 .. typeid(p).init.length];
destroy(p);
alloc.deallocate(support);
}
deallocate doesn't care about the the length of initial static layout of a class.
Comment #3 by github-bugzilla — 2016-03-03T13:52:06Z