10

在 D 中,所有数组字面量都是动态数组,因此由 GC 分配。

即使在这个简单的例子中:

int[3] a = [10, 20, 30];

该数组是堆分配的,然后复制到a.

你应该如何在没有堆分配的情况下初始化一个静态数组?

您可以手动完成:

int[3] a = void;
a[0] = 10;
a[1] = 20;
a[2] = 30;

但这充其量是乏味的。

有没有更好的办法?

4

5 回答 5

9
static const int[3] a = [10, 20, 30];

这将在数​​据段中放置一个常量副本。您可以通过简单的赋值 ( ) 在堆栈上创建一个副本(不涉及堆分配auto copy = a;)。

于 2011-07-19T18:12:12.757 回答
3

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.

于 2011-07-19T17:50:43.370 回答
1

这只是一个编译器错误。我在 DMD 的 bugzilla 中看到了它。现在应该修复它(DMD 2.055)。

于 2011-09-14T07:47:28.143 回答
1

我认为您可能有点误会:在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];不会/不应该在堆上分配任何东西

于 2011-07-19T18:31:53.303 回答
1

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 还是可以编译,所以我们知道数组初始值设定项没有分配。

于 2017-05-14T01:19:17.530 回答