Какой смысл иметь статические массивы

У меня нет фона в 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 также имеет массивы переменной длины.

Другие вопросы по тегам