Segfault при вызове метода c ++ - PullRequest
0 голосов
/ 07 апреля 2010

Я довольно новичок в c ++, и я немного озадачен этой проблемой. Я пытаюсь присвоить переменную от вызова метода в другом классе, но это всегда segfaults. Мой код компилируется без предупреждений, и я проверил, что все переменные в gdb верны, но сам вызов функции, похоже, вызывает ошибку segfault. Код, который я использую, примерно такой:

class History{
 public:
 bool test_history();
};
bool History::test_history(){
    std::cout<<"test"; //this line never gets executed
    //more code goes in here
    return true;
}


class Game{
 private:
    bool some_function();
 public:
    History game_actions_history;

};


bool Game::some_function(){

  return game_actions_history.test_history();

}

Любые советы или рекомендации с благодарностью!

РЕДАКТИРОВАТЬ: я отредактировал код, чтобы больше не было local_variable, и значение возвращается напрямую. Но это все-таки segfaults. Что касается публикации реального кода, он довольно большой, какие части я должен публиковать?

Ответы [ 4 ]

4 голосов
/ 07 апреля 2010

Я успешно использовал valgrind с большим количеством ошибок.

а вы пытались запустить gdb с coredump, вызванным segfault? от человека GDB:

gdb program core

Для создания coredump вам может потребоваться установить:

ulimit -c unlimited
4 голосов
/ 07 апреля 2010

Из того, что я вижу, нет ничего плохого в отображаемом коде. Тем не менее, segfaults часто являются хорошим признаком того, что у вас повреждена память. Это происходит в другом месте, помимо того, что вы показали, и только влияет на код здесь. Я бы посмотрел любое место, где вы имеете дело с массивами, указателями или любыми ручными взаимодействиями с памятью.

1 голос
/ 07 апреля 2010

Код в порядке, но пример слишком неполный, чтобы сказать, что не так. Некоторые вещи, которые я бы предложил:

Добавить распечатки к деструктору и конструктору каждого класса:

Game::Game()               { cerr << this << " Game::Game" << endl; }
Game::Game(Game const&)    { cerr << this << " Game::Game(Game const&)" << endl; }
Game::~Game()              { cerr << this << " Game::~Game" << endl; }
bool Game::some_function() { cerr << this << " Game::some_function()" << endl; ... }

Это покажет:

  • Указатели нулевых объектов.
  • Плохие / удаленные указатели классов.

Во-вторых, для отладки я настоятельно рекомендовал бы отправлять распечатки в cerr вместо cout. cout обычно буферизуется (для эффективности) перед выводом, cerr - нет (по крайней мере, раньше). Если ваша программа завершает работу без выполнения своих обработчиков ошибок, at_exit и т. Д., Вы с большей вероятностью увидите вывод, если он небуферизован и распечатан немедленно.

В-третьих, если ваши объявления классов находятся в заголовке, определения классов находятся в одном файле cpp, а код, который использует класс в другом, вы можете получить такой вид сбоя, если ни один из файлов cpp не был перекомпилирован после того, как вы изменили заголовок.

Некоторые другие возможности:

  • переполнение стека: вы распределили много памяти в стеке из-за глубокой рекурсии или выделяете объекты, содержащие большие массивы данных, в качестве локальных переменных (то есть не созданы или кучи с новыми или malloc))
  • поврежденный класс vtable (обычно это возможно только из-за ошибок зависимостей в ваших инструментах сборки),
  • поврежденный указатель vtable объекта: возможно из-за неправильного использования указателей: использование указателей на удаленную память или неправильная запись по используемому адресу. Маловероятно в вашем примере, потому что нет виртуальных функций.
  • сохранение указателя или ссылки на объект, размещенный в стеке, который был удален: приведенный выше код распечатки раскроет этот случай.
1 голос
/ 07 апреля 2010

Снято в темноте. (Game*)this равно NULL?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...