Ошибка сегментации из-за нехватки памяти в C - PullRequest
7 голосов
/ 19 ноября 2010

Этот код дает мне ошибку сегментации примерно в половине случаев:

int main(int argc, char **argv) {
    float test[2619560];
    int i;
    for(i = 0; i < 2619560; i++)
        test[i] = 1.0f;
}

Мне действительно нужно выделить гораздо больший массив, есть ли способ, позволяющий операционной системе получать больше памяти?

Я использую Linux Ubuntu 9.10

Ответы [ 4 ]

23 голосов
/ 19 ноября 2010

Вы переполняете максимальный размер стека по умолчанию, который составляет 8 МБ.

Вы можете увеличить размер стека, например. для 32 МБ:

ulimit -s 32767

... или вы можете переключиться на распределение с помощью malloc:

float *test = malloc(2619560 * sizeof test[0]);
6 голосов
/ 19 ноября 2010

Прямо сейчас вы выделяете (или, по крайней мере, пытаетесь) 2619560*sizeof(float) байт в стеке.По крайней мере, в большинстве типичных случаев стек может использовать только ограниченный объем памяти.Вместо этого вы можете попытаться определить его static:

static float test[2619560];

Это вытащит его из стека, поэтому вместо него обычно можно использовать любую доступную память.В других функциях определение чего-либо как static меняет семантику, но в случае main это не имеет большого значения (кроме теоретической возможности рекурсивного main).

1 голос
/ 19 ноября 2010

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

2.6M с плавающей запятой не так уж много, и даже в 32-битной системе вы должны быть в порядке с адресным пространством.

Если вам нужно выделить очень большой массив, обязательно используйте 64-битную систему (при условии, что у вас достаточно памяти!).32-битные системы могут адресовать только около 3G на процесс, и даже тогда вы не можете выделить все это как один непрерывный блок.

0 голосов
/ 19 ноября 2010

Это стек переполнения. Вам лучше использовать функцию malloc, чтобы получить объем памяти больше размера стека, который вы можете получить из "ulimit -s".

...