Ответ 1
static const int[3] a = [10, 20, 30];
Это поместит постоянную копию в сегмент данных. Вы можете создать копию в стеке (которая не включает выделение кучи) с простым назначением (auto copy = a;
).
В 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;
).
Я думаю, что если бы вы могли объявить литерал как immutable
глобально, тогда используйте это как инициализатор, там не будет выделение кучи - но я могу ошибаться, я не уверен.
Я думаю, вы можете ошибаться: http://www.digitalmars.com/d/2.0/arrays.html#static-init-static
Статическая инициализация статических массивов
Статические инициализации представлены списком значений элементов массива заключен в []. Значениям может быть необязательно предшествует индекс и a:. Если индекс не указан, он устанавливается на предыдущий индекс плюс 1 или 0, если это первое значение.
-snip -
Эти массивы являются статическими, когда они отображаются в глобальной области. В противном случае они должны быть отмечены с помощью константных или статических классов хранения, чтобы сделать их статическими массивами.
с примером кода
int[3] a = [ 1:2, 3 ]; // a[0] = 0, a[1] = 2, a[2] = 3
это означает, что const a[3] = [10, 20, 30];
не будет/не должен выделять ничего в куче
Это просто ошибка компилятора. Я видел это в DMD bugzilla. Он должен быть исправлен к настоящему времени (DMD 2.055).
2017 UPDATE: в любой последней версии 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, мы знаем, что инициализатор массива не выделяет.