2010-06-16 3 views
5

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

int main() 
{ 

    int nums_size = 2000000000; 

    int nums[nums_size]; 

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


    return 0; 

} 

ответ

21

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

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

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

+0

Даже если бы это было не так, 2000000000 * 4 = 8 000 000 000 байт на 32-битной платформе. Это почти 2^33, что больше, чем доступная память. –

+0

@ Крис: Да, я на самом деле не считал нули до тех пор, пока я не отправил. Это целые числа! –

+0

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

4
int nums_size = 2000000000; 

int nums[nums_size]; 

Это не значит, 2000000000 байт Интс, это означает 2000000000 элементы типа INT, который на 32-битную платформу означает, что вы уничтожаете почти 8 Гб памяти - это невозможно.

+0

... и в стеке!- Кабум! –

3

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

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

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

+1

Компилятор будет обрабатывать его правильно (если он был внутри размера памяти 2^32), но операционная система не позволит стеку получить такой большой размер. –

+0

не просто C/C++ практически на любом языке, на котором выполняется распределение на основе стека (т.е. почти все из них) – Spudd86

0

Эта версия прекрасно работает на моем компьютере:

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; 
} 

(Ну, давайте будем честны It начинается штраф, но вскоре уходит в своп.).

+0

И я предполагаю, что ваша версия работает на 64-битной платформе. Из его комментария 2^31 он определенно не работает на 64-битной ОС. –

+0

-1 за то, что у меня больше памяти, чем у меня (просто шучу). – cdonner

+0

Комментарий @Chris 2^31 не говорит вам, используете ли вы 32-разрядную или 64-разрядную версию. Я думаю, что gcc по умолчанию 32-битные ints на 64-битных платформах. – sigfpe

2

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

1

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

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