D 动态阵列的内存布局是什么?
我的第一个问题是,这在内部看起来如何?我的假设是: 如果Foo是一个类,那么array是指向Foo对象指针数组的指针D 动态阵列的内存布局是什么?,d,D,我的第一个问题是,这在内部看起来如何?我的假设是: 如果Foo是一个类,那么array是指向Foo对象指针数组的指针vector v//c++ 如果Foo是一个结构,那么array是指向Foo对象数组的指针向量v//c++ 是在D中连续的动态数组,像在C++中一样, < p> 数组< /C> >本身是一个结构,它具有 siZeIt长度< /C> >和 fo*pTr> /Calp> 这在(查找阵列)中进行了描述 是的,存储在连续内存中。D动态数组如下所示: auto array = new F
vector v//c++
如果Foo是一个结构,那么array是指向Foo对象数组的指针<代码>向量v//c++
是在D中连续的动态数组,像在C++中一样,
< p> <代码>数组< /C> >本身是一个结构,它具有<代码> siZeIt长度< /C> >和<代码> fo*pTr> /Calp> 这在(查找阵列)中进行了描述是的,存储在连续内存中。D动态数组如下所示:
auto array = new Foo[100];
执行newt[size]
基本上就是执行以下操作:
struct Array(T) {
size_t length;
T* ptr;
}
是的,元素的内存是与C++类似的。剩下的问题是关于T是什么的细节,你的想法是对的:
<> > <代码> fo是一个类,即任何引用<代码> FoO < /C> >像指针一样工作,因此它就像C++中的“代码> Fo**/Cuffo>数组”,当T是一个类,总是等于<> >空> *sieOS/<代码> *,对象按引用工作。如果是一个结构,它是完全就位的,比如C++中的代码>向量< /代码>。 顺便说一句,结构的有趣之处在于:由于对齐问题,它们不一定打包在数组中。考虑以下事项:Array!T array;
array.length = size;
array.ptr = GC.malloc(size * T.sizeof);
Foo.sizeof
你可能期望6岁。。。但实际上是8,因为uint将在4字节边界上对齐,导致s
之后有两个字节的填充。如果将align(1)
添加到uint字段,则会覆盖该字段,将i
放在内存中s
的旁边。但是,因为我们讨论的是数组,所以您将希望节点Foo[]
元素将/仍然/有自己的对齐方式Foo.sizeof==8
因此Foo[2]
的大小仍然是16。内部的align(1)
只是将填充移动到结构的末尾,对于数组的情况,它没有完全移除填充
如果您想要一个在元素之间没有填充的Foo[]
,您还需要将align(1)
添加到结构的外部:align(1)struct Foo{/*…*/}
。然后Foo.sizeof==6,数组中没有填充
- 如果您想获得对象本身的大小,例如,如果您正在编写自己版本的
,也有一种方法可以做到这一点:新MyClass
。但是D是通过引用来实现类的,因为在存在继承的情况下更容易保持健全\uu traits(classInstanceSize,Foo)
array.dup
或foo[]=bar[]
显式复制D中的数据
进一步阅读:
- (“数组操作”是
的东西,“数组属性”有foo[]=bar[]
,还有更多)dup
- (请参阅“阵列”标题-这描述了长度/ptr布局)
- (讨论阵列本身与您操作的片,并解释有关动态阵列内存管理的一些内部内容)
- (您可以在那里找到有关结构对齐的信息)
新的也传递了所需的大小(考虑子类),这实际上是一个非常有用的答案。
struct Foo {
ushort s;
uint i;
}