и что оба способа потребуют использования free ().
Нет, только первый нуждается в бесплатном использовании. Второй размещается в стеке. Это делает его невероятно быстрым для распределения. Смотрите здесь:
void doit() {
/* ... */
/* SP += 10 * sizeof(int) */
int a[10];
/* ... (using a) */
} /* SP -= 10 */
Когда вы создаете его, компилятор во время компиляции знает его размер и выделит для него правильный размер в стеке. Стек - это большой кусок непрерывной памяти, расположенный где-то. Помещение чего-либо в стек просто увеличит (или уменьшит в зависимости от вашей платформы) указатель стека. Выход из области действия сделает обратное, и ваш массив будет освобожден. Это произойдет автоматически. Поэтому переменные, созданные таким образом, имеют автоматический срок хранения.
Использование malloc отличается. Он закажет произвольный большой кусок памяти (из места, которое называется freestore ). Среде выполнения придется искать достаточно большой блок памяти. Размер можно определить во время выполнения, поэтому компилятор обычно не может оптимизировать его во время компиляции. Поскольку указатель может выходить из области видимости или копироваться, отсутствует внутренняя связь между выделенной памятью и указателем, которому назначен адрес памяти, поэтому память все еще выделяется, даже если вы давно покинули функцию , Вы должны позвонить бесплатно, передав адрес, который вы получили от malloc вручную, если пришло время сделать это.
Некоторая «недавняя» форма C, называемая C99, позволяет вам давать массивам размер времени выполнения. Т.е. вам разрешено делать:
void doit(int n) {
int a[n]; // allocate n * sizeof(int) size on the stack */
}
Но эту функцию лучше избегать, если у вас нет причин ее использовать. Одной из причин этого является то, что это не отказоустойчиво: если больше нет доступной памяти, может произойти все что угодно Другое дело, что C99 не очень переносим среди компиляторов.