Segfaulting вызывает функцию - PullRequest
2 голосов
/ 23 января 2012

у меня следующий класс heirarchy:

ICSL::ISystemModel
ICSL::ISystemModelAffine : public ISystemModel
ICSL::Quadrotor::SystemModelQuadrotor : public QObject, ISystemModelAffine
ICSL::Quadrotor::SystemModelQuadrotorSimulated : public public SystemModelQuadrotor

Затем в другом классе я определяю

SystemModelQuadrotor mDynamicModelReal;
SystemModelQuadrotorSimulated mDynamicModelSimulated;

Во время инициализации я вызываю множество функций для установки переменных на mDynamicModelReal и mDynamicModelSimulated без проблем. Позже я вызываю некоторые функции из ISystemModel для доступа к некоторым переменным, которые отлично работают для mDynamicModelReal, но для segfaults для mDynamicModelSimulated. При проверке в gdb значение переменной является правильным, и оно, похоже, знает, что это за функция, но жалуется, когда пытается вызвать реальную функцию (на основании моего ограниченного понимания этих вещей). Вот gdb-зондирование после того, как оно сработало для вызова mDynamicModelSimulated.getName()

(gdb) print mDynamicModelSimulated.mName
$19 = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x810658 "quadGaui5"}}
(gdb) print mDynamicModelSimulated.getName
$20 = {const std::string (ICSL::ISystemModel * const)} 0x44f506 <ICSL::ISystemModel::getName()>
(gdb) print mDynamicModelSimulated.getName()
Cannot access memory at address 0x4082c00000000030

А вот определение getName ()

Class ISystemModel {
public:
...
virtual std::string const getName(){return mName;};
...
protected:
...
std::string mName;
...
};

Я не понимаю, почему он не может выполнить этот вызов функции. Я обнаружил, что если я удаляю «virtual» из определения функции, то это не вызывает ошибки, но я не понимаю, почему это имеет значение. Где мне искать источник проблемы?

Ответы [ 3 ]

1 голос
/ 24 января 2012

Убедитесь, что все, что QObject выделено в куче, а не в стеке.Они не очень хорошо играют со стеком.

0 голосов
/ 23 января 2012

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

Если это коррупция, то это могло произойти в любое время до этого момента. Добавьте протоколирование или проследите и посмотрите, где вызовы к getName() начинают терпеть неудачу.

0 голосов
/ 23 января 2012

Я предполагаю, что вы вызываете виртуальную функцию из конструктора, которая не разрешена и может вызвать непредвиденное поведение. Вы можете проверить это:).

...