2016-12-05 4 views
1

У меня возникает проблема, мне нужно сделать хруст больших данных, и создание слишком больших массивов, по-видимому, вызывает Segmentation fault (core dumped). Вот тиражирование проблемы:Слишком большие вложенные массивы приводят к сбою сегментации (ядро сбрасывается)

int main() { 
struct { char a[2000][12] } b[2000]; 
return 0; } 

Я использую Archlinux 64 бита, cc как компилятор, ulimit -s возвращает 8192, который является странным, так как у меня есть 24 Гб оперативной памяти. Любая идея, как решить проблему? Я думаю, что это связано с stack и heap, но я понятия не имею, что это такое.

+2

Это переполнение стека! –

+1

@KirillBulygin Этот сайт достиг своей цели и будет закрыт. – nicomp

+0

Вам нужно выделить из кучи. Размер стека обычно ограничен 1 МБ или около того. Прочитайте malloc/бесплатно. – OldProgrammer

ответ

1

В основном вы пытаетесь выделить 2000 * 12 * 2000/1024 = 46875 КБ в стеке, но разрешите использовать только 8192 КБ. Быстрое исправление - установить ulimit -s 50000.

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

+0

Что приведет к более быстрой программе: увеличение размера стека или выделение динамической памяти? – ChiseledAbs

+0

С точки зрения скорости эти способы практически одинаковы, но выделение большой памяти на стеке просто неверно, отчасти потому, что есть возможность случайно использовать память после завершения вызова функции (и содержимое памяти должно быть повреждено другими данными), также потому, что вам нужно будет называть 'ulimit (1)' или 'ulimit (2)', чтобы расширить размер стека (а также на некоторых архитектурах, отличных от настольных компьютеров, просто невозможно иметь большой стек). –

1
ulimit -s 

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

Вы можете увеличить его, используя ulimit -s unlimited. Но я бы предложил использовать динамическое распределение памяти для таких больших массивов, так как размер вашего массива составляет ~ 48 МБ, и вы можете легко столкнуться с проблемами, если это не будет недоступно в стеке, главным образом из-за того, что сбой «выделения стека» трудно обнаружить.

1

Использование памяти стека, объявляя ваш массив локальной переменной. Используйте свою кучу с распределением памяти:

typedef struct { 
    char a[2000][12]; 
} bigArray; 

int main(void) { 
    bigArray *array; 
    array = (bigArray*)malloc(2000 * sizeof(bigArray)); 

    // Do stuff with array here 

    free(array); 
    return 0; 
} 
Смежные вопросы