D maloc/免费指定集装箱问题
多亏了支持,我可以编写一些简单的程序,但是,由于SIGSEGV,我的实际尝试失败了。在我看来,内存是通过malloc有效分配的,那么,为什么我访问了错误的内存呢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
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();
}
}