2017-02-08 17 views
3

Основываясь на комментарий кого-то в другом потоке:Большой VLA Переполнение

Власа ввести больше проблем, чем решить, потому что вы никогда не знаете если декларация будет врезаться при х слишком велика для стек.

Этот код будет переполняться, потому что sizeof(a) слишком долго для стека:

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int n = 100000000; 
    int a[4][n]; 

    printf("%zu\n", sizeof(a)); 

    return 0; 
} 

Но это одна не может, потому что sizeof(a) 8 (размер указателя на моем компьютере):

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int n = 100000000; 
    int (*a)[n]; 

    printf("%zu\n", sizeof(a)); 
    a = malloc(sizeof(*a) * 4); 
    free(a); 
    return 0; 
} 

Является ли мое предположение правильным?

Можем ли мы определить, является ли использование VLA опасным или нет (может переполняться) на основе объекта sizeof?

+2

'int (* a) [n];' не является VLA. Это указатель на VLA. – chux

+1

Почему вы умножаете 'sizeof (* a)' на 4? Вы делаете массив из 100000000x4? – dasblinkenlight

+1

Кроме того, как отметил chux, 'int (* a) [n]' является указателем на VLA, а не сам VLA. – dasblinkenlight

ответ

4

int (*a)[n]; не является VLA, а является указателем на VLA. Поэтому примеры OP 2 не являются достаточно близким сравнением.


Как @M.M отметил, предотвращая переполнение стека проблема с любым автоматическим распределением. Рекурсия может чрезмерно потреблять стек. Локальные большие переменные могут чрезмерно потреблять стек.

VLA является просто одним из наиболее вероятных для использования вопиющим образом.

// Qualified use of VLA 
int len = snprintf(NULL, 0 "%d", some_int); 
assert(len > 0); 
char vla_good[len+1]; 
len = snprintf(vla_good, len+1, "%d", some_int); 

// Unqualified 
int x; 
scanf("%d", &x); 
char vla_bad[x]; // who knowns what x may be, did scanf() even work? 

Власа ввести больше проблем, чем решить, потому что вы никогда не знаете, если заявление будет врезаться при х слишком велика для стека.

Можем ли мы определить, опасно ли использование VLA?

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

Обратите внимание, что VLA, доступный с момента, когда C99 поддерживается в C11.

VLA не плохие, это just drawn that way.