Ошибка сегментации при доступе к (не указателю) переменной-члену в экземпляре класса Qt - PullRequest
1 голос
/ 11 ноября 2010

У меня есть некоторые проблемы с ошибкой сегментации, вызванной доступом к переменной-члену в приложении Qt.Мой опыт ошибок сегментации показал, что они, как правило, являются результатом доступа к области памяти, которая находится за пределами границ.Тем не менее, я изо всех сил пытаюсь выяснить, почему это будет иметь место в моем коде.

Рассматриваемый класс является подклассом QFrame и содержит ряд переменных-членов, включая одну, первоначально названную m_Zoom извведите unsigned int.Когда создается кадр, вызывается ряд функций, которые вызывают настройку масштаба, а затем рисуется окно.Это все отлично работает.Существует несколько способов изменить уровень масштабирования: открыть новый файл или нажать + или -.Они читают существующий уровень масштабирования, а затем решают, следует ли изменить его.Простое чтение существующего уровня масштабирования вызывает ошибку сегментации.

Обратите внимание, что эта переменная не является указателем или массивом или чем-то необычным.Определение было следующим:

class MyClass : public QFrame
{
    Q_OBJECT

public:
    MyClass(QWidget *parent = 0);
    void SetZoomLevel(unsigned int zoom);
    void ZoomIn();

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);

private:
    // A number of private functions for performing calculations

    // Some variables including:
    double m_OriginShift;
    unsigned int m_Zoom;
    // Some more variables
};

Функция paintEvent и все функции события mouse* обращаются к m_Zoom, и они прекрасно работают (мышь используется для перемещения обзора).Конструктор вызывает SetZoomLevel (что в основном m_Zoom = zoom).Опять же, это работает без проблем.ZoomIn начинается с:

void MyClass::ZoomIn()
{
    qDebug() << "Zoom In";
    unsigned int existingZoom = m_Zoom; // [1]
    qDebug() << "Existing zoom is " << existingZoom;

    ...

В этой функции происходит ошибка сегментации, прежде чем вторая qDebug сообщает что-либо.

Я попытался пройти приложение в gdb cygwin иЯ добираюсь до строки, помеченной [1] и набираю stepi, и получаю немедленный segfault.

Переместив переменную (в случае, если что-то еще перезаписывает ее местоположение), изменил на использование указателя с malloc d память, переместила его в отдельную структуру, переместила его в отдельный класс (как с экземпляром члена, так и с указателем члена со строкой new в конструкторе) и, возможно, несколько других случайных и неудачных актов отчаяния,У меня полностью закончились идеи.

Пожалуйста, кто-нибудь может предложить какие-нибудь хорошие способы отладки этой проблемы?

Я использую Qt 4.6.3 на компиляции Windows XP сGNU Make 3.81 и g ++ версии 4.4.0 (из mingw, поставляемого с установщиком Qt).

1 Ответ

10 голосов
/ 11 ноября 2010

Хотя это дикое предположение, есть вероятность, что вы вызываете этот метод для нулевого объекта.

Обратите внимание, что:

unsigned int existingZoom = m_Zoom;

эквивалентно

unsigned int existingZoom = this->m_Zoom;

Если вы вызвали этот метод из нулевого указателя:

someUninitializedPtr->ZoomIn();

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

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