Объявление переменной вызывает ошибку сегментации - PullRequest
11 голосов
/ 28 декабря 2010

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

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

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;, программа немедленно падает.

Может кто-нибудь мне помочь

Ответы [ 2 ]

14 голосов
/ 28 декабря 2010

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

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

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

1 голос
/ 28 декабря 2010

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

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

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

...