Segfault Проблемы с массивом структур внутри структуры - PullRequest
1 голос
/ 15 марта 2011

Редактировать: Первый комментатор сообщает, что в коде нет явных ошибок, поэтому я пересмотрел пост с большим количеством кода. Извиняюсь за длину. Снова возникает ошибка, когда я ссылаюсь на строковые переменные в подструктуре ... обратите внимание, что если я удаляю первую запись, которая позже вызывает segfault в segfaults из-за записи в другую строку var. Обратите внимание, что в этом сценарии другие элементы подструктуры (например, double Volume) правильно записаны без ошибок времени выполнения.

Редактировать 2: По предложению Дейва я запустил Valgrind на исполняемом файле с поддержкой отладки. То, что это выплюнуло было:

Редактировать 3: Видимо у меня была версия, которая malloc вместо прямого массива внутри инициализатора. Удаление это решило проблему. Я воздаю должное Дэйву за это, так как valgrind помогает мне исправить всевозможные утечки / проблемы с памятью! Спасибо за помощь, хотя ....

Строка 36 - та, на которой она не работает (прокомментировано ниже)

- код удален для предотвращения распространения

Я объявляю экземпляр моей структуры верхнего уровня (sim_t) в main. Программа segfaults, как только я пытаюсь записать в строки внутри подструктуры. Записывает в другие переменные субструктуры, например, double, ints и т. д. выполнялись правильно, когда я запускал программу в GDB.

Кажется, что-то очевидно, что я здесь скучаю. Кто-нибудь видит проблему с этим кодом?

(И для записи, пожалуйста, не комментируйте заглавные буквы, я следую стандарту MSDN по именованию.)

Ответы [ 3 ]

2 голосов
/ 15 марта 2011

Вы добавляете «boxX_start.pdb» в stringstream на каждой итерации, не очищая поток. Использование памяти может очень быстро увеличиваться при большом значении NUMBEROFBOXES. Попробуйте это

void InitSimpleVars(sim_t & MySim)
{
  std::stringstream in;

  MySim.StartTime = clock();

  //INITIALIZE Box Sim Vars...                                                                                
  for (unsigned int BoxNumber = 0; BoxNumber < NUMBEROFBOXES; BoxNumber++)
    {
      in.str("");                                                                                           
      in << "box" << BoxNumber << "_start.pdb";
      MySim.Box[BoxNumber].InitialConfigPDB = in.str(); //SEGFAULT HERE, according to GDB                     
    }
}

добавление в in.str (""); очистить поток. Может быть, есть лучший способ очистить это, но я не знаю об этом, если есть.

2 голосов
/ 15 марта 2011

Если вы скомпилируете это с -Wall, возможно, вы получите предупреждения об изменениях упаковки? У меня были подобные сбои из-за #pragma pack до заголовков стандартной библиотеки.

Или, после еще одного просмотра вашего кода, возможно, измените ваши BOX1 и BOX2 определения на 0 и 1, а не 1 и 2 - учитывая, что в вашем массиве есть только 2 блока.

2 голосов
/ 15 марта 2011

Полагаю, вы переполняете стек. Если и NUMBEROFBOXES, и sizeof(box_t) несколько большие, то sizeof(sim_t) будет очень большим, и тогда даже один экземпляр sim_t переполнит ваш стек.

Если вы не можете каким-либо образом уменьшить sizeof(sim_t), то вам нужно разместить объект в куче (например, с new) или в статическом хранилище (например, в качестве глобальной переменной). *


EDIT

Я все еще подозреваю, что переполнение стека, но все еще трудно сказать на данный момент. Запустите вашу программу под GDB и выполните эти команды и сообщите нам, каковы результаты:

$ gdb myprogram
(gdb) run
...
Program received signal SIGSEGV, Segmentation fault.
(gdb) bt
...
(gdb) list
...
(gdb) disas
...
(gdb) info reg
...
(gdb) info inferior
...

Последняя команда дает вам PID программы. Затем из другого терминала выполните эту команду:

# Replace PID here with the PID of the program being debugged above
$ cat /proc/PID/maps

Информация из этих команд должна помочь определить, вызвана ли проблема переполнением стека.

...