问题
interface Bar{
}
class Foo: Bar{
int i;
this(int _i){
i = _i;
}
}
void main(){
import std.experimental.allocator.mallocator;
import std.experimental.allocator;
auto f = Mallocator.instance.make!Foo(42);
Bar b = f;
Mallocator.instance.dispose(b);// Bad
}
I am currently creating my own smart pointer and I am now extending them to also work with classes and polymorphism.
The problem I am running into is subtyping, I am transferring a pointer from Box!Foo
to Box!Bar
if Foo implements Bar.
But then Box!Bar goes out of scope and calls dispose on the interface and it crashes.
How do I dispose an object if I only have an interface pointer?
I guess I could just store the pointer under the hood as void*
.
compiled with DMD64 D Compiler v2.071.0
*** Error in `./bin/breeze_task': free(): invalid pointer: 0x00000000018196c0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f8491fa7725]
/lib/x86_64-linux-gnu/libc.so.6(+0x7ff4a)[0x7f8491faff4a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f8491fb3abc]
./bin/breeze_task(_D3std12experimental9allocator10mallocator10Mallocator10deallocateMOFNiAvZb+0x51)[0x498a6d]
./bin/breeze_task(_D3std12experimental9allocator77__T7disposeTOS3std12experimental9allocator10mallocator10MallocatorTC3app3BarZ7disposeFKOS3std12experimental9allocator10mallocator10MallocatorC3app3BarZv+0x73)[0x48f513]
./bin/breeze_task(_Dmain+0x39)[0x48f241]
./bin/breeze_task(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv+0x1f)[0x49de57]
./bin/breeze_task(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv+0x21)[0x49dda1]
./bin/breeze_task(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv+0x2b)[0x49de13]
./bin/breeze_task(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv+0x21)[0x49dda1]
./bin/breeze_task(_d_run_main+0x1d2)[0x49dd12]
./bin/breeze_task(main+0x20)[0x4901f0]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f8491f50830]
./bin/breeze_task(_start+0x29)[0x48f119]
======= Memory map: ========
00400000-00517000 r-xp 00000000 08:15 398722 /home/maik/projects/breeze/bin/breeze_task
00717000-00718000 r--p 00117000 08:15 398722 /home/maik/projects/breeze/bin/breeze_task
00718000-0072e000 rw-p 00118000 08:15 398722 /home/maik/projects/breeze/bin/breeze_task
0072e000-0072f000 rw-p 00000000 00:00 0
017fc000-0182e000 rw-p 00000000 00:00 0 [heap]
7f848c000000-7f848c021000 rw-p 00000000 00:00 0
7f848c021000-7f8490000000 ---p 00000000 00:00 0
7f8490c68000-7f8490c6d000 r-xp 00000000 08:12 141260 /usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0
7f8490c6d000-7f8490e6c000 ---p 00005000 08:12 141260 /usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0
7f8490e6c000-7f8490e6d000 r--p 00004000 08:12 141260 /usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0
7f8490e6d000-7f8490e6e000 rw-p 00005000 08:12 141260 /usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0
7f8490e6e000-7f8490fe0000 r-xp 00000000 08:12 132861 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f8490fe0000-7f84911e0000 ---p 00172000 08:12 132861 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f84911e0000-7f84911ea000 r--p 00172000 08:12 132861 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f84911ea000-7f84911ec000 rw-p 0017c000 08:12 132861 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f84911ec000-7f84911f0000 rw-p 00000000 00:00 0
7f84911f0000-7f84912aa000 r-xp 00000000 08:12 416324 /usr/lib/nvidia-364/libGLdispatch.so.0
7f84912aa000-7f84914aa000 ---p 000ba000 08:12 416324 /usr/lib/nvidia-364/libGLdispatch.so.0
7f84914aa000-7f84914b9000 rw-p 000ba000 08:12 416324 /usr/lib/nvidia-364/libGLdispatch.so.0
7f84914b9000-7f84914d9000 rw-p 00000000 00:00 0
7f84914d9000-7f84914ea000 r-xp 00000000 08:12 416297 /usr/lib/nvidia-364/libGLX.so.0
7f84914ea000-7f84916e9000 ---p 00011000 08:12 416297 /usr/lib/nvidia-364/libGLX.so.0
7f84916e9000-7f84916ea000 rw-p 00010000 08:12 416297 /usr/lib/nvidia-364/libGLX.so.0
7f84916ea000-7f849170a000 rw-p 00000000 00:00 0
7f849170a000-7f8491713000 r-xp 00000000 08:12 141278 /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
7f8491713000-7f8491912000 ---p 00009000 08:12 141278 /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
7f8491912000-7f8491913000 r--p 00008000 08:12 141278 /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
7f8491913000-7f8491914000 rw-p 00009000 08:12 141278 /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
7f8491914000-7f8491925000 r-xp 00000000 08:12 141258 /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f8491925000-7f8491b24000 ---p 00011000 08:12 141258 /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f8491b24000-7f8491b25000 r--p 00010000 08:12 141258 /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f8491b25000-7f8491b26000 rw-p 00011000 08:12 141258 /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f8491b26000-7f8491b2b000 r-xp 00000000 08:12 141256 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f8491b2b000-7f8491d2a000 ---p 00005000 08:12 141256 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f8491d2a000-7f8491d2b000 r--p 00004000 08:12 141256 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f8491d2b000-7f8491d2c000 rw-p 00005000 08:12 141256 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f8491d2c000-7f8491d2e000 r-xp 00000000 08:12 141245 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f8491d2e000-7f8491f2e000 ---p 00002000 08:12 141245 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f8491f2e000-7f8491f2f000 r--p 00002000 08:12 141245 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f8491f2f000-7f8491f30000 rw-p 00003000 08:12 141245 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f8491f30000-7f84920f0000 r-xp 00000000 08:12 281619 /lib/x86_64-linux-gnu/libc-2.23.so
7f84920f0000-7f84922ef000 ---p 001c0000 08:12 281619 /lib/x86_64-linux-gnu/libc-2.23.so
7f84922ef000-7f84922f3000 r--p 001bf000 08:12 281619 /lib/x86_64-linux-gnu/libc-2.23.so
7f84922f3000-7f84922f5000 rw-p 001c3000 08:12 281619 /lib/x86_64-linux-gnu/libc-2.23.so
7f84922f5000-7f84922f9000 rw-p 00000000 00:00 0
7f84922f9000-7f849230f000 r-xp 00000000 08:12 267115 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f849230f000-7f849250e000 ---p 00016000 08:12 267115 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f849250e000-7f849250f000 rw-p 00015000 08:12 267115 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f849250f000-7f8492516000 r-xp 00000000 08:12 281614 /lib/x86_64-linux-gnu/librt-2.23.so
7f8492516000-7f8492715000 ---p 00007000 08:12 281614 /lib/x86_64-linux-gnu/librt-2.23.so
7f8492715000-7f8492716000 r--p 00006000 08:12 281614 /lib/x86_64-linux-gnu/librt-2.23.so
7f8492716000-7f8492717000 rw-p 00007000 08:12 281614 /lib/x86_64-linux-gnu/librt-2.23.so
7f8492717000-7f849281f000 r-xp 00000000 08:12 281470 /lib/x86_64-linux-gnu/libm-2.23.so
7f849281f000-7f8492a1e000 ---p 00108000 08:12 281470 /lib/x86_64-linux-gnu/libm-2.23.so
7f8492a1e000-7f8492a1f000 r--p 00107000 08:12 281470 /lib/x86_64-linux-gnu/libm-2.23.so
7f8492a1f000-7f8492a20000 rw-p 00108000 08:12 281470 /lib/x86_64-linux-gnu/libm-2.23.so
7f8492a20000-7f8492a21000 r-xp 00000000 08:12 141239 /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1.0.0
7f8492a21000-7f8492c20000 ---p 00001000 08:12 141239 /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1.0.0
7f8492c20000-7f8492c21000 r--p 00000000 08:12 141239 /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1.0.0
7f8492c21000-7f8492c22000 rw-p 00001000 08:12 141239 /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1.0.0
7f8492c22000-7f8492c25000 r-xp 00000000 08:12 281620 /lib/x86_64-linux-gnu/libdl-2.23.so
7f8492c25000-7f8492e24000 ---p 00003000 08:12 281620 /lib/x86_64-linux-gnu/libdl-2.23.so
7f8492e24000-7f8492e25000 r--p 00002000 08:12 281620 /lib/x86_64-linux-gnu/libdl-2.23.so
7f8492e25000-7f8492e26000 rw-p 00003000 08:12 281620 /lib/x86_64-linux-gnu/libdl-2.23.so
7f8492e26000-7f8492e2f000 r-xp 00000000 08:12 141252 /usr/lib/x86_64-linux-gnu/libXcursor.so.1.0.2
7f8492e2f000-7f849302e000 ---p 00009000 08:12 141252 /usr/lib/x86_64-linux-gnu/libXcursor.so.1.0.2
7f849302e000-7f849302f000 r--p 00008000 08:12 141252 /usr/lib/x86_64-linux-gnu/libXcursor.so.1.0.2
7f849302f000-7f8493030000 rw-p 00009000 08:12 141252 /usr/lib/x86_64-linux-gnu/libXcursor.so.1.0.2
7f8493030000-7f8493032000 r-xp 00000000 08:12 141268 /usr/lib/x86_64-linux-gnu/libXinerama.so.1.0.0
7f8493032000-7f8493231000 ---p 00002000 08:12 141268 /usr/lib/x86_64-linux-gnu/libXinerama.so.1.0.0
7f8493231000-7f8493232000 r--p 00001000 08:12 141268 /usr/lib/x86_64-linux-gnu/libXinerama.so.1.0.0
7f8493232000-7f8493233000 rw-p 00002000 08:12 141268 /usr/lib/x86_64-linux-gnu/libXinerama.so.1.0.0
7f8493233000-7f84932a0000 r-xp 00000000 08:12 141103 /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
7f84932a0000-7f84934a0000 ---p 0006d000 08:12 141103 /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
7f84934a0000-7f84934a1000 r--p 0006d000 08:12 141103 /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
7f84934a1000-7f84934a2000 rw-p 0006e000 08:12 141103 /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
7f84934a2000-7f849352f000 r-xp 00000000 08:12 416287 /usr/lib/nvidia-364/libGL.so.1.0.0
7f849352f000-7f849372f000 ---p 0008d000 08:12 416287 /usr/lib/nvidia-364/libGL.so.1.0.0
7f849372f000-7f8493730000 rw-p 0008d000 08:12 416287 /usr/lib/nvidia-364/libGL.so.1.0.0
7f8493730000-7f8493731000 rw-p 00000000 00:00 0
7f8493731000-7f849373b000 r-xp 00000000 08:12 141276 /usr/lib/x86_64-linux-gnu/libXrandr.so.2.2.0
7f849373b000-7f849393a000 ---p 0000a000 08:12 141276 /usr/lib/x86_64-linux-gnu/libXrandr.so.2.2.0
7f849393a000-7f849393b000 r--p 00009000 08:12 141276 /usr/lib/x86_64-linux-gnu/libXrandr.so.2.2.0
7f849393b000-7f849393c000 rw-p 0000a000 08:12 141276 /usr/lib/x86_64-linux-gnu/libXrandr.so.2.2.0
7f849393c000-7f8493941000 r-xp 00000000 08:12 141294 /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1.0.0
7f8493941000-7f8493b40000 ---p 00005000 08:12 141294 /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1.0.0
7f8493b40000-7f8493b41000 r--p 00004000 08:12 141294 /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1.0.0
7f8493b41000-7f8493b42000 rw-p 00005000 08:12 141294 /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1.0.0
7f8493b42000-7f8493c77000 r-xp 00000000 08:12 141241 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f8493c77000-7f8493e77000 ---p 00135000 08:12 141241 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f8493e77000-7f8493e78000 r--p 00135000 08:12 141241 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f8493e78000-7f8493e7c000 rw-p 00136000 08:12 141241 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f8493e7c000-7f8493e94000 r-xp 00000000 08:12 281618 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8493e94000-7f8494093000 ---p 00018000 08:12 281618 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8494093000-7f8494094000 r--p 00017000 08:12 281618 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8494094000-7f8494095000 rw-p 00018000 08:12 281618 /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8494095000-7f8494099000 rw-p 00000000 00:00 0
7f8494099000-7f84940a8000 r-xp 00000000 08:12 141266 /usr/lib/x86_64-linux-gnu/libXi.so.6.1.0
7f84940a8000-7f84942a7000 ---p 0000f000 08:12 141266 /usr/lib/x86_64-linux-gnu/libXi.so.6.1.0
7f84942a7000-7f84942a8000 r--p 0000e000 08:12 141266 /usr/lib/x86_64-linux-gnu/libXi.so.6.1.0
7f84942a8000-7f84942a9000 rw-p 0000f000 08:12 141266 /usr/lib/x86_64-linux-gnu/libXi.so.6.1.0
7f84942a9000-7f84942ca000 r-xp 00000000 08:12 142612 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f84942ca000-7f84944c9000 ---p 00021000 08:12 142612 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f84944c9000-7f84944ca000 r--p 00020000 08:12 142612 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f84944ca000-7f84944cb000 rw-p 00021000 08:12 142612 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f84944cb000-7f84944f1000 r-xp 00000000 08:12 281615 /lib/x86_64-linux-gnu/ld-2.23.so
7f84945b6000-7f84946c3000 rw-p 00000000 00:00 0
7f84946ed000-7f84946f0000 rw-p 00000000 00:00 0
7f84946f0000-7f84946f1000 r--p 00025000 08:12 281615 /lib/x86_64-linux-gnu/ld-2.23.so
7f84946f1000-7f84946f2000 rw-p 00026000 08:12 281615 /lib/x86_64-linux-gnu/ld-2.23.so
7f84946f2000-7f84946f3000 rw-p 00000000 00:00 0
7ffeb88e3000-7ffeb8904000 rw-p 00000000 00:00 0 [stack]
7ffeb890f000-7ffeb8911000 r--p 00000000 00:00 0 [vvar]
7ffeb8911000-7ffeb8913000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Program exited with code -6
This is the dispose function:
void dispose(A, T)(auto ref A alloc, T p)
if (is(T == class) || is(T == interface))
{
if (!p) return;
auto support = (cast(void*) p)[0 .. typeid(p).init.length];
destroy(p);
alloc.deallocate(support);
}
The problem seems to be this line
auto support = (cast(void*) p)[0 .. typeid(p).init.length];
interface Bar{
}
class Foo: Bar{
int i;
this(int _i){
i = _i;
}
}
void main(){
import std.experimental.allocator.mallocator;
import std.experimental.allocator;
auto f = Mallocator.instance.make!Foo(42);
Bar b = f;
auto support = (cast(void*) b)[0 .. typeid(b).init.length];
writeln("length ", support.length);
Mallocator.instance.dispose(b);// Bad
}
It actually prints length 0
because typeid(b).init.length
is also 0. It appears that something here is very wrong.
Also the addresses of f
and b
from cast(void*)
are different, see How do I get the address of an object with an interface?
回答1:
Okay the problem was that I was using dub and had emsi_container as a dependency. emsi_container has an outdated version of std.experimental.allocator as a dependency which overshadowed the version that ships with the compiler.
This bug is fixed in the newest version of std.experimental.allocator.
来源:https://stackoverflow.com/questions/37868594/disposing-a-class-with-an-interface