2016-01-24 5 views
2

Я был поражен, увидев, что этот код работает. Я не мог понять, почемуСоздание динамического массива без malloc

#include<stdio.h> 
int main(){ 
    int row,col,i,j; 
    scanf("%d %d",&row,&col); 
    int a[row][col]; 
    for(i=0;i<row;i++) 
     for(j=0;j<col;j++) 
      scanf("%d",&a[i][j]); 
    for(i=0;i<row;i++){ 
     for(j=0;j<col;j++) 
      printf("%d ",a[i][j]); 
     printf("\n"); 
    } 
} 

С С компилируемый язык, то как она выделяет память для массива а [строка] [столбец]? Поскольку во время компиляции значение строки и столбца неизвестно, то как он может сделать машинный код и задать адресное пространство для программы? Почему это работает как интерпретатор языка работал бы, если этот способ создать динамический массив, то почему мы учили использовать таНос для создания динамического массива в С.

+0

На самом деле, они не являются динамика массива, но пол-динамика –

ответ

3

Массивы переменной длины являются стандартной функцией C с C99.

Как это выделение памяти для массива a[row][col]

После того, как значение row и col известно, нет никаких проблем для скомпилированного кода, чтобы сделать это выделение в автоматическом хранилище (обычно называемый «стек»).

Как он умеет код машины и задает адресное пространство для программы?

Компилятор белки расстояние значения row и col для внутреннего использования машинного кода, который он генерирует. Инструкции, которые ссылаются на a[i][j], просмотрите размеры, сделайте математику, добавьте смещение и получите адрес, как если бы во время компиляции были известны row и col.

Эта функция меняет несколько других вещей - например, sizeof больше не является чисто операцией во время компиляции, поскольку размер VLA должен быть вычислен во время выполнения.

почему мы учили использовать malloc для создания динамического массива в С.

malloc дает большую гибкость, чем VLA. Например, вы можете вернуть созданный с помощью malloc массив из вашей функции, а VLA автоматически освобождается, как только функция завершится. Кроме того, malloc с меньшей вероятностью запускает вашу программу из памяти, поскольку динамическая область хранения более щедрая, чем автоматическая.

Например, если вы попытаетесь ввести 20002000 для своей программы, это, скорее всего, произойдет сбой. Тем не менее, это не будет иметь никаких проблем, выделяющие тот же объем памяти с malloc:

int (*a)[col] = malloc(row*col*sizeof(int)); 
0

That's feature of C99. Причина использования malloc в том, что он выделяет пространство не в стеке, но куча - и куча - это место, где должны храниться «тяжелые» данные, поскольку пространство стека сильно ограничено. Больше чем это; неспособность выполнить распределение стека обычно приводит к сбою программы - при распределении с malloc возвращается указатель NULL, который позволяет вам действовать элегантно.

+0

Нет эта функция с более ранней версией C тоже. – ASEN

+1

В стандарте кучи или стека нет упоминания (по крайней мере, не в контексте отдельных областей памяти), не говоря уже о любых требованиях VLA, которые должны быть выделены в стеке – Peter

+4

@ASEN - первый стандарт C, который поддерживает VLA был стандартом С 1999 года. Некоторые реализации поддерживали такие вещи, как расширение до этого. – Peter

Смежные вопросы