D maloc/免费指定集装箱问题

D maloc/免费指定集装箱问题,d,D,多亏了支持,我可以编写一些简单的程序,但是,由于SIGSEGV,我的实际尝试失败了。在我看来,内存是通过malloc有效分配的,那么,为什么我访问了错误的内存呢 module test.main; import std.stdio; import std.c.stdlib; import std.conv; class example { int num; this() { writeln("example ctor"); num = 1

多亏了支持,我可以编写一些简单的程序,但是,由于SIGSEGV,我的实际尝试失败了。在我看来,内存是通过malloc有效分配的,那么,为什么我访问了错误的内存呢

module test.main;
import std.stdio;
import std.c.stdlib;
import std.conv;

class example
{
    int num;
    this()
    {
        writeln("example ctor");
        num = 1000;
    }
    ~this()
    {
        writeln("example dtor");
    }
}

struct simpleVector(T)
{
    T * buffer = null;
    int size = 0;
    this(int _size)
    {
        size = _size;
        buffer = cast(T*)malloc(T.sizeof*size);
        for (int i=0; i<size;++i)
        {
           ctor(buffer[i])
        }
    }
    ~this()
    {
        for (int i=0; i<size;++i)
        {
           dtor(buffer[i]);
        }
        size = 0;
        free(buffer);
    }
    void dtor(ref T ob)
    {
        ob.__dtor();
    }
        void ctor(ref T ob)
    {
        ob.__ctor();
    }

};

void main()
{
    simpleVector!example vc = simpleVector!example(5);
}
moduletest.main;
进口std.stdio;
进口标准c.stdlib;
进口标准conv;
课例
{
int-num;
这()
{
书面形式(“举例”);
num=1000;
}
~z~这个()
{
书面形式(“示例dtor”);
}
}
结构simpleVector(T)
{
T*buffer=null;
int size=0;
这个(整数大小)
{
大小=_大小;
缓冲区=cast(T*)malloc(T.sizeof*大小);
for(inti=0;i(这个答案是针对问题的一部分。)

这两行是错误的:

emplace!T(cast(T*)buffer[i*T.sizeof]);
dtor(*(cast(T*)buffer[i*T.sizeof]));
buffer
不保存指向对象的指针,而是保存对象数据本身。因此,在转换到
t*
之前,先获取一个指针:

emplace!T(cast(T*)&buffer[i*T.sizeof]);
dtor(*(cast(T*)&buffer[i*T.sizeof]));
更新:否)更好的是,正确键入
buffer

更新:不,请参见下文)甚至可能制作
缓冲区
一个D数组:

更新: 我遗漏了一个重要的细节:
T
是类类型。这意味着:

  • T.sizeof
    是引用的大小。您需要数据的大小,即
    \u traits(classInstanceSize,T);
  • buffer
    不应键入
    T*
    T[]
    。这将是一个引用数组。
    byte*
    byte[]
    可以
  • 您需要使用
    (void[]chunk,auto ref Args Args)
    emplace的重载(其他用于非类类型)
  • 你必须尊重一致性
  • dtor
    的参数不应为
    ref
总而言之(并非100%确定这是正确的):

struct simpleVector(T)
{
枚举实例大小=uu特征(classInstanceSize,T);
枚举填充=实例大小%std.traits.classInstanceAlignment!T;
枚举paddedInstanceSize=实例大小+填充;
字节*缓冲区=空;
int size=0;
这个(整数大小)
{
大小=_大小;
buffer=cast(字节*)malloc(paddedInstanceSize*大小);

对于(inti=0;iYeah,没有SIGSEGV,但是,我的构造函数没有被调用(它没有调用示例ctor)。如果我编写函数ctor(看起来像dtor)并调用ctor(buffer[i]),它调用构造函数(仅第一次)但是它以SIGSEGV结束。怎么了?我错过了类类型的特性。更新了答案。这个问题的答案对我来说没有什么意义。现在看起来你想要的只是缓冲区。但是如果你不想
放置
实例,你可以
新建
它们;不需要
\u-ctor
__dtor
fiddling。我尝试创建“对象池”来分配和取消分配对象。
T* buffer = null;
buffer = cast(T*)malloc(T.sizeof*size);
emplace!T(&buffer[i]);
dtor(buffer[i]));
T[] buffer;
buffer = (cast(T*)malloc(T.sizeof*size))[0 .. size];
free(buffer.ptr);
struct simpleVector(T)
{
    enum instanceSize = __traits(classInstanceSize, T);
    enum padding = instanceSize % std.traits.classInstanceAlignment!T;
    enum paddedInstanceSize = instanceSize + padding;
    byte * buffer = null;
    int size = 0;
    this(int _size)
    {
        size = _size;
        buffer = cast(byte*)malloc(paddedInstanceSize*size);
        for (int i=0; i<size;++i)
        {
            emplace!T(buffer[i*paddedInstanceSize .. (i+1)*paddedInstanceSize]);
        }
    }
    ~this()
    {
        for (int i=0; i<size;++i)
        {
           dtor(cast(T) &buffer[i*paddedInstanceSize]);
        }
        size = 0;
        free(buffer);
    }
    void dtor(T ob)
    {
        ob.__dtor();
    }

}