Какой смысл иметь статические массивы
У меня нет фона в C или C++, поэтому статические массивы меня немного озадачивают. Для чего они? Почему они расположены в стеке?
Я думаю, что есть преимущество в производительности. Распределение стека происходит быстрее и нет необходимости в сборке мусора. Но почему длина должна быть известна во время компиляции? Не могли бы вы создать массив фиксированного размера во время выполнения и разместить его в стеке?
Динамические массивы или слайсы в D представлены структурой, которая содержит указатель и свойство длины. То же самое верно для статических массивов? Как они представлены?
Если вы передаете их в функцию, они копируются полностью (если вы не используете ref), что за этим стоит?
Я понимаю, что динамические массивы и слайсы гораздо важнее в D, чем статические массивы, поэтому документация не останавливается на них очень долго, но я все же хотел бы иметь немного больше информации. Я предполагаю, что особенности статических массивов связаны с тем, как работает распределение стека.
2 ответа
Статические массивы родом из языка Си, где звонки (медленные) alloc
были обескуражены до крайности из-за утечек памяти (когда вы забыли освободить выделенный массив), двойного освобождения (в результате...), висячих указателей (все опасности ручного управления памятью, которых можно избежать с помощью GC)
это означало, что такие конструкции, как
int foo(char* inp){
char[80] buff;
strcpy(inp,buff);//don't do this this is a invite for a buffer overflow
//...
return 1;
}
были распространены вместо вызовов alloc/free, когда вам нужно убедиться, что все выделенное вами было освобождено ровно один раз в течение программы
технически вы МОЖЕТЕ динамически размещать в стеке (используя сборку, если хотите), однако это может вызвать некоторые проблемы с кодом, так как длина будет известна только во время выполнения и уменьшить возможную оптимизацию, которую может применить компилятор (развернув итерацию над ним для пример)
статические массивы в основном используются для буферов из-за быстрого выделения в стеке
ubyte[1024] buff=void;//assigning void avoids the initializer for each element cause we are writing to it first thing anyway
ubyte[] b;
while((b=f.rawRead(buff[])).length>0){
//...
}
они могут неявно преобразовываться в срез массива (или явно с помощью оператора среза []
) так что вы можете использовать их почти взаимозаменяемо с обычными динамическими массивами
Статические массивы являются типами значений в D2. Без статических массивов не было бы простого способа иметь 100 элементов в структуре, которые фактически хранятся в структуре.
Статические массивы несут свой размер как часть своего типа. Это позволяет вам, например, объявить: alias ubyte[16] IPv6Address;
В отличие от C, статические массивы D2 являются типами значений насквозь. Это означает, что они передаются по значению функциям, например структурам. Статические массивы обычно ведут себя как структуры с N элементами в том, что касается выделения памяти и копирования.
Кстати, вы можете использовать alloca
выделить переменное количество памяти в стеке. C также имеет массивы переменной длины.