C программирование, почему это объявление большого массива производит отказ сегментации?

Этот код производит отказ сегментации во время объявления массива. Я смущен относительно того, почему это происходит. Я намеренно выбрал 2000000000 как значение, потому что это ниже 2^31 и может вписаться в целочисленную переменную.

int main()
{

    int  nums_size = 2000000000;

    int nums[nums_size];

    int i;
    for(i = 0; i < nums_size; i++) {
        nums[i] = i;
    }


    return 0;

}
5
задан Artelius 16 June 2010 в 00:11
поделиться

6 ответов

Ну, во-первых, это два миллиарда целых чисел. Если у вас 32-битное адресное пространство, а размер int на вашей платформе составляет четыре байта (типично для 32-битной платформы), вы не можете хранить такое количество целых чисел, точка.

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

Если вам нужен действительно большой массив, вы должны динамически выделить его с помощью malloc () (и если вы это сделаете, обязательно освободите его с помощью free () , когда вы покончено с этим!).

21
ответ дан 18 December 2019 в 05:39
поделиться

Эта версия отлично работает на моем ПК:

const int nums_size = 2000000000;
int nums[nums_size];

int main()
{
    int i;
    for(i = 0; i < nums_size; i++) {
        nums[i] = i;
    }

    return 0;
}

(Ну, давайте будем честными. Она запускается нормально, но вскоре переходит в режим подкачки.)

0
ответ дан 18 December 2019 в 05:39
поделиться

Вы размещаете в стеке гигантский массив. Практически ни один компилятор C / C ++ не справится с этим правильно.

Возможно, вам удастся переместить его в глобальные объекты (которые будут выделять пространство статически, отображая память в исполняемом файле во время компиляции) или переключившись на массив malloc 'd.

Конечно, это все еще МНОГО памяти, которую нужно запросить за один раз, но, по крайней мере, упомянутые мной методы позволят избежать немедленного segfault.

3
ответ дан 18 December 2019 в 05:39
поделиться

Локальные переменные размещаются в стеке.Приложению предоставляется фиксированный объем стека (обычно от 1 до 8 МБ, в зависимости от ОС). Общее правило - использовать malloc () для выделения больших объемов данных.

2
ответ дан 18 December 2019 в 05:39
поделиться
int  nums_size = 2000000000;

int nums[nums_size];

Не означает 2000000000 байт целых чисел, это означает 2000000000 элементов типа int, что на 32-битной платформе означает что вы потребляете почти 8 ГБ памяти - это невозможно.

4
ответ дан 18 December 2019 в 05:39
поделиться

Ответ на ваш вопрос прост: stackoverflow . Нет-нет, не сайт, а собственно процесс «переполнения стека». У вас недостаточно стека для хранения этого массива. Так просто. Делать это в системах с ограниченным объемом памяти - чистое безумие. Также см. этот вопрос .

1
ответ дан 18 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: