Объявление переменной вызывает ошибку сегментации

Я не понимаю причину ошибки ошибки сегментации в моей программе. Код доступен здесь

В строке 29 объявляю переменную PclImage, определенную с помощью typedef, как массив структуры. Определение типа PclImage следующее (из файла src/libMyKinect.h):

typedef struct {
    int valid;
    float x;
    float y;
    float z;
    unsigned char blue;
    unsigned char green;
    unsigned char red;
} Point3d;

typedef Point3d PclImage[480][640];

Программа работает хорошо, но когда я объявляю второй PclImage, я получаю ошибку сегментации, как только запускаю программу.

Например, если в строке 30 первого файла я добавляю PclImage bgPcl;, программа немедленно сработает.

Кто-нибудь может мне помочь?

Ответ 1

Если вы объявите PclImage как локальную переменную (в стеке), вы, вероятно, получите ошибку сегментации из-за.

PclImage - массив с 307 200 элементами, каждый из которых (вероятно) размером около 20 байтов, поэтому весь массив имеет размер около 6 МБ. Очень маловероятно, чтобы стек был достаточно большим, чтобы содержать два из этих массивов; он может даже не быть достаточно большим, чтобы содержать один (как правило, обычно он безопасен для большинства настольных ОС, предполагая, что у вас есть как минимум 1 МБ пространства стека).

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

Ответ 2

Я согласен с Джеймсом, что распределение этих больших массивов в стеке, скорее всего, является причиной. Однако каждый PclImage содержит только около 6Meg каждый. Если вы не работаете в среде с ограниченной памятью, это должно быть выполнимо. Раньше я выделял гораздо большие массивы в стеке. Даже на встроенных системах.

Предложение Джеймса использовать malloc, вероятно, исправит его (стоит попробовать только для проверки проблемы). Тем не менее, я считаю, что это хорошая политика, чтобы избежать динамического распределения, когда это возможно. Возможными альтернативами malloc было бы объявление массивов во внешнем контексте или увеличение размера стека потоков. Созданные пользователем процессы и/или потоки часто имеют достаточно небольшие стеки, выделенные им по умолчанию. Это может быть довольно простой вопрос, чтобы найти, где это установлено, и предоставить ему достаточно большой стек для ваших нужд.

Например, если это выполняется из потока, созданного с помощью подпрограммы Windows CreateThread(), второй параметр управляет размером стека. Если вы по умолчанию используете 0 (как это делает большинство людей), он принимает размер стека по умолчанию. Насколько я могу судить, это "только" 1 МБ.