2011-12-29 2 views
2

Я наткнулся на этот пример C99 массивы переменной длины в Википедии:C99 массивы переменной длины Пример Wikipedia

float read_and_process(int n) 
{ 
    float vals[n]; 

    for (int i = 0; i < n; i++) 
     vals[i] = read_val(); 
    return process(vals, n); 
} 

Является ли это неправильно? У меня создалось впечатление, что массивы переменной длины все еще являются просто указателями, что означает, что приведенный выше код передает устаревший указатель vals функции process (...).

+3

Массивы не указатели. Они просто * распадаются на указатели - досадно легко, некоторые скажут. – cHao

+0

+1 для «Массивы не указатели». См. Также раздел 6 [comp.lang.c FAQ] (http://c-faq.com) –

ответ

6

Указатель не истек. Это указатель на действительную память до конца функции read_and_process. Это означает, что он все еще определяется при вызове процесса.

Это будет пример недопустимого использования:

float read_and_process(int n) 
{ 
    float vals[n]; 

    for (int i = 0; i < n; i++) 
     vals[i] = read_val(); 
    return vals; 
} 
+0

О, хорошо, что имеет смысл. Пока вы наращиваете стек, адрес памяти все равно должен быть действительным. – Jeff

+1

@Jeff: лучший способ взглянуть на это: массив (или любой локальный объект, не являющийся «статическим») продолжает существовать до тех пор, пока функция, создавшая его, не вернется. (Фактически он привязан к закрывающему * блоку *, но в этом случае он одинаковый.) Время жизни локального объекта - это период * времени * во время выполнения, а не область текста программы. Вызов 'process' не завершает выполнение' read_and_process', поэтому массив все еще существует. –

1

Не забывайте, что фрейм стека, который содержит все автоматические переменные read_and_process() «s, в том числе float vals[n], остается в силе и в памяти, когда process() является казнены.

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