2015-05-15 4 views
4

У меня возникла особая проблема. Я разработал C++-программу на кластере Linux на работе. Я попытался использовать его на машине Ubuntu 14.04, но программа, состоящая из 6 файлов: main.hpp, main.cpp (зависит от) sarsa.hpp, sarsa.cpp (класс Sarsa) (зависит от) wec.hpp, wec.cpp, компилируется, но когда я его запускаю, он либо возвращает segmenation fault, либо не вводит одну фундаментальную функцию класса Sarsa.Ошибка сегментации на одном компьютере с Linux, но не с кодом C++

Основной код вызывает конструктор и инкубационных функции без проблем:

Sarsa run; 
    run.setVectorSize(memory,3,tilings,1000); 

т.д.

Однако, он не может запустить публичную функцию episode, так как learningRate, который должен содержать большое число, возвращает 0 для всех эпизодов (итераций).

learningRate[episode]=run.episode(numSteps,graph);} 

Я пытался отладить код с GDB, который возвращенный:

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000408f4a in main() at main.cpp:152 
152  learningRate[episode]=run.episode(numSteps,graph);} 

Я также попытался valgrind, которая вернулась:

==10321== Uninitialised value was created by a stack allocation 
==10321== at 0x408CAD: main (main.cpp:112) 

Но никаких проблем утечки памяти.

мне было интересно, если есть установка, чтобы попытаться отладить внешний файл sarsa.cpp, так как я думаю, что класс, вероятно, будет culpript

В файле, я использую C++ язык V11 (я бы однако ожидайте ошибки во время компиляции), поэтому я даже скомпилировал g++ -std=c++0x, но никаких улучшений не было.

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

Заранее благодарю за помощь.

Исправление: main.cpp:

Определение глобального массива: `#define numEpisodes 10

INT learningRate [numEpisodes];`

К концу функции main:

for (int episode; episode<numEpisodes; episode++) { if (episode==(numEpisodes-1)) { // Save the simulation data only at the graph=true;} // last episode learningRate[episode]=run.episode(numSteps,graph);}

+1

1. Поскольку segfault происходит в коде, полученном из 'main.cpp', это, казалось бы, лучшее место для начала. Наиболее вероятными причинами segfault в main.cpp: 152 было бы 'learningRate' неинициализированным указателем (обратите внимание на предупреждение Valgrind) или' epsiode', не являющимся допустимым индексом в него статическим или динамическим массивом, на который ссылается 'learningRate'. –

+1

2. Наличие разделения источников между несколькими файлами не представляет особой или необычной задачи для 'gdb' или большинства других отладчиков. Отладка программы, построенной из нескольких источников Just Works. Если отладчик может найти 'main.cpp' (что он может), и вы не изменили относительные местоположения других источников, тогда он найдет и другие. –

+1

В конце моего вопроса я добавил части 'main.cpp', где можно найти' learningRate'. Я не понимаю, почему 'learningRate' должен быть неинициализированным указателем –

ответ

2

Как только вы только что добавили к вопросу, проблема возникает, потому что вы не инициализировали переменную episode. Поведение любого кода, использующего его значение до его назначения, не определено, поэтому вполне разумно, что программа ведет себя по-разному в одной среде, чем в другой.

2

Ошибка сегментации указывает на недопустимый доступ к памяти. Обычно это означает, что где-то вы читаете или записываете конец конца массива, или через недопустимый указатель, или через объект, который уже был освобожден. Вы не обязательно получаете ошибку сегментации в точке, где возникает ошибка; например, вы можете написать за конец массива на метаданные кучи, что впоследствии приведет к сбою при попытке выделить или освободить несвязанный объект. Поэтому вполне разумно, чтобы программа работала на одной системе, но с другой.

В этом случае я бы начал с обзора learningRate[episode].Каково значение episode? Является ли он в пределах learningRate?

0

мне было интересно, если есть установка, чтобы попытаться отладить внешний файл sarsa.cpp, так как я думаю, что класс, вероятно, будет culpript

It's possible to set breakpoints in functions other than main.cpp.

перерыв место

Установите контрольную точку в данном месте , который можно указать имя функции, номер строки, или адрес инструкции.

По крайней мере, я думаю, что это ваш вопрос. You'll also need to know how to step into functions.

Что еще более важно, вам нужно узнать, что ваши инструменты пытаются рассказать вам. Segfault - это реакция операционной системы на попытку разыменовать память, которая не принадлежит вам. Одной из распространенных причин этого является попытка разыменования NULL. Другой будет пытаться разыменовать указатель, который никогда не инициализировался. Сообщение об ошибке Valgrind предполагает, что вы можете иметь унифицированный указатель.

Без кода я не могу сказать, почему указатель не инициализирован при запуске программы на вашей домашней системе, но, по-видимому, инициализируется при запуске на работе. Я подозреваю, что у вас нет необходимых данных в вашей домашней системе, но вам нужно исследовать и понять это. Основной вопрос, который следует задать себе, - «что у моего домашнего компьютера отличается от рабочего компьютера dmy?»