在 D 中,所有数组字面量都是动态数组,因此由 GC 分配。
即使在这个简单的例子中:
int[3] a = [10, 20, 30];
该数组是堆分配的,然后复制到a
.
你应该如何在没有堆分配的情况下初始化一个静态数组?
您可以手动完成:
int[3] a = void;
a[0] = 10;
a[1] = 20;
a[2] = 30;
但这充其量是乏味的。
有没有更好的办法?
在 D 中,所有数组字面量都是动态数组,因此由 GC 分配。
即使在这个简单的例子中:
int[3] a = [10, 20, 30];
该数组是堆分配的,然后复制到a
.
你应该如何在没有堆分配的情况下初始化一个静态数组?
您可以手动完成:
int[3] a = void;
a[0] = 10;
a[1] = 20;
a[2] = 30;
但这充其量是乏味的。
有没有更好的办法?
static const int[3] a = [10, 20, 30];
这将在数据段中放置一个常量副本。您可以通过简单的赋值 ( ) 在堆栈上创建一个副本(不涉及堆分配auto copy = a;
)。
I think if you could declare the literal as immutable
globally, then use that as the initializer, there's no heap allocation -- but I may be wrong, I'm not sure.
这只是一个编译器错误。我在 DMD 的 bugzilla 中看到了它。现在应该修复它(DMD 2.055)。
我认为您可能有点误会:在http://www.digitalmars.com/d/2.0/arrays.html#static-init-static
静态数组的静态初始化
静态初始化由包含在 [ ] 中的数组元素值列表提供。可以选择在值前面加上一个索引和一个:。如果未提供索引,则将其设置为前一个索引加 1,如果是第一个值,则设置为 0。
-剪辑-
这些数组出现在全局范围内时是静态的。否则,它们需要使用 const 或静态存储类进行标记,以使其成为静态数组。
带代码示例
int[3] a = [ 1:2, 3 ]; // a[0] = 0, a[1] = 2, a[2] = 3
这意味着const a[3] = [10, 20, 30];
不会/不应该在堆上分配任何东西
2017 更新:在任何最新版本的 DMD 中,在静态数组上使用数组初始化器不再分配,即使静态数组是局部变量(即堆栈分配)。
您可以自己验证这一点,方法是创建一个初始化静态数组的函数,然后将该函数标记为 @nogc 并观察它是否编译。例子:
import std.random;
import std.stdio;
int[4] testfunc(int num) @nogc
{
return [0, 1, num, 3];
}
int main()
{
int[4] arr = testfunc(uniform(0, 15));
writeln(arr);
return 0;
}
由于 testfunc() 尽管是 @nogc 还是可以编译,所以我们知道数组初始值设定项没有分配。