문제

어와 관련하여 segfaults(때로는 sigabrts 때문에 나쁜 mallocs)도 추가들로 구성되을 QMap 로 키 안에 소멸의 문제에 대 클래스가-그것을 생각 할 수 있는 뭔가가들로 구성되의 암시적 공유 모델과 범위가 있습니다.

나는 문제에 대한 행동으로 창에서 MDI,이 문제에 대한 몇 가지 QGLWidget 파생 뷰포트 인스턴스이다.하위 창 있 QMap< 들로 구성되,QVariant>래퍼 클래스 프로젝트가 포함된 파일의 설정을 사용할 경우위 창을 닫은,그것의 소멸자를 통화 문제에 대한::deleteChildren()삭제하는 각각의 뷰포트.뷰포트에서는 소멸자가 현재 설정이 저장되를 잠수함으로 창의 설정을 예를 들어:

QString dir = QString( "camera/" ) + name;
sWin.setSetting( dir + "/Projection",
                 static_cast< int >( camera_->getProjectionType() ) );

이 sWin.setSetting()를 호출한 각각의 특성을 나는 저장하,'스윈'에 대한 참조를 QMap 래퍼 클래스를 삭제한 끝에서의 창 소멸자.모든 것이 잘 때까지 setSetting()호출이:

inline void setSetting( const QString& key, QVariant value )
{
    //  projectSettings_ is a standard QMap< QString, QVariant >.
    projectSettings_.insert( key, value );
}

이 설정은 미 을 위한 첫 번째는 뷰포트, 에서 첫 번째 setSetting()호출이의 두 번째,세그멘테이션에서 발생한다:

inline QString::QString(const QString &other) : d(other.d)
{ Q_ASSERT(&other != this); d->ref.ref(); }

나고 깊은 복사가 실패할 때 나들로 구성되 참조가 전달되 QMap?그렇다면 이유는 무엇입니까?이들로 구성되 내가 만들어가지 않는 범위를 벗어나 아직으로 소멸자는 반환되지 않습니다.고 왜 이렇게 실패에 두 번째는 뷰포트지 않는 첫 번째?

때때로 내가을 얻을 수 sigabrt malloc():메모리 손상 에서 운전자에서+setSetting()라인의 첫 번째 코드 예제입니다.그러나 다시 시작의 두 번째는 뷰포트의 파괴,처음이 아니다.

나는 죄송한 말 질문,하지만 많은 양의 코드가 참여에 걸쳐 많은 번역 단위입니다.어떤 단서를 이 문제에 대한 큰 도움이 될 것입니다!

미리 감사드립니다.Cam


업데이트

를 변경했는데 첫 번째 코드 샘플을 사용:

QString* dir = new QString( "camera/" );
*dir += name;
sWin.setSetting( *dir + "/Projection",
                 static_cast< int >( camera_->getProjectionType() ) );

로에 대한 테스트 범위는 문제입니다.그 때때로 작동,그리고 다른 시간에게 정확히 동일한 에러;그래서 아마도 힙들로 구성되는 파괴되고,그에 따라 달라지는지 그것의 메모리 위치를 덮어 쓰기.그러나 이것도 아무 의미 없으로 나를 부르지 않에서 삭제를,그것도 나는 응용 프로그램을 닫(단 MDI sub window)!


더 코드

sWin 성에 힙면 새로운 창이 인스턴스화됩니다.그것은으로 가져가 뷰포트 클래스'소멸자로부터 참조 방식에서 내 sub 창:

inline Sy_project& getProject() { return *project_; }

Sy_project(현재)간단한 래퍼 클래스를 위한 QMap.나의 완벽한 뷰포트 베이스 클래스 소멸이(그것은 실패한 여기에서 파생된 클래스):

Sy_abstractGLViewport::~Sy_abstractGLViewport()
{
    //  Write last viewport settings.
    QString name = objectName();
    Sy_project& sWin = projWindow_->getProject();
    QString dir = QString( "camera/" ) + name;

    //  Avoid "taking address of temporary" warning.
    QVector3D pos = camera_->getPosition();
    QVector3D foc = camera_->getFocalPoint();

    //  Save camera settings.  Dies on first setSetting() call.
    sWin.setSetting( dir + "/Projection",
                     static_cast< int >( camera_->getProjectionType() ) );
    sWin.setSetting( dir + "/position",
                     QVariant( 84, static_cast< void* >( &pos ) ) );
    sWin.setSetting( dir + "/focalPoint",
                     QVariant( 84, static_cast< void* >( &foc ) ) );
    sWin.setSetting( dir + "/FOV", camera_->getFOV() );
    sWin.setSetting( dir + "/nearClip", camera_->getPerspectiveClipRange()[0] );
    sWin.setSetting( dir + "/farClip", camera_->getPerspectiveClipRange()[1] );

    delete camera_;
}

Valgrind

후에 사용하 Valgrind 의 memcheck 내가 발견한 수많은 항목이 보이는 유사한 내 stacktrace.지,그것을 사용하기 전에 나는 여전히 해독하지만,이 말하는 내 Sy_project 클래스(래퍼 QMap)삭제 후에 이 setSetting()호출을 떠나 QMap 잘못된 참조하나요?

==12418== Invalid read of size 4
==12418==    at 0x805D872: QMap<QString, QVariant>::detach_helper() (qmap.h:730)
==12418==    by 0x805D380: QMap<QString, QVariant>::detach() (in /home/cbamber85/workspace/Syren GUI/Syren)
==12418==    by 0x805CDEE: QMap<QString, QVariant>::insert(QString const&, QVariant const&) (qmap.h:537)
==12418==    by 0x805CA33: Sy_project::setSetting(QString const&, QVariant) (Sy_project.h:50)
==12418==    by 0x805A78C: Sy_abstractGLViewport::~Sy_abstractGLViewport() (Sy_abstractGLViewport.cpp:67)
==12418==    by 0x808EDBC: Sy_QtGLViewport::~Sy_QtGLViewport() (Sy_QtGLViewport.cpp:91)
==12418==    by 0x808EE0E: Sy_QtGLViewport::~Sy_QtGLViewport() (Sy_QtGLViewport.cpp:100)
==12418==    by 0x4D66D63: QObjectPrivate::deleteChildren() (in /usr/lib/libQtCore.so.4.6.3)
==12418==    by 0x4306DDF: QWidget::~QWidget() (in /usr/lib/libQtGui.so.4.6.3)
==12418==    by 0x46FBE0E: QFrame::~QFrame() (in /usr/lib/libQtGui.so.4.6.3)
==12418==    by 0x475F173: QSplitter::~QSplitter() (in /usr/lib/libQtGui.so.4.6.3)
==12418==    by 0x475F1D1: QSplitter::~QSplitter() (in /usr/lib/libQtGui.so.4.6.3)
==12418==  Address 0xacf5b9c is 4 bytes inside a block of size 8 free'd
==12418==    at 0x40266AD: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==12418==    by 0x808D60F: Sy_project::~Sy_project() (Sy_project.h:30)
==12418==    by 0x808C9C6: Sy_subWindow::~Sy_subWindow() (Sy_subWindow.cpp:55)
==12418==    by 0x808CA84: Sy_subWindow::~Sy_subWindow() (Sy_subWindow.cpp:57)
==12418==    by 0x4D66482: qDeleteInEventHandler(QObject*) (in /usr/lib/libQtCore.so.4.6.3)
==12418==    by 0x4D67967: QObject::event(QEvent*) (in /usr/lib/libQtCore.so.4.6.3)
==12418==    by 0x4302ACB: QWidget::event(QEvent*) (in /usr/lib/libQtGui.so.4.6.3)
==12418==    by 0x42A9C63: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.6.3)
==12418==    by 0x42B1CA3: QApplication::notify(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.6.3)
==12418==    by 0x806010F: Sy_application::notify(QObject*, QEvent*) (Sy_application.cpp:14)
==12418==    by 0x4D54E0D: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib/libQtCore.so.4.6.3)
==12418==    by 0x4D589B3: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib/libQtCore.so.4.6.3)
도움이 되었습니까?

해결책

나는 생각 Sy_project 체의 포인터와 따라서 참조를 가리키는 이미 파괴된 시간에 의해 소멸자의 Sy_abstractGLViewport 라고 합니다.우 valgrind 목록의 소멸자 Sy_project 호출하기 전에 소멸자의 Sy_abstractGLViewport.

그래서를 호출할 때 inline Sy_project& getProject() { return *project_; } 내 Sy_abstractGLViewport 소멸자,당신은 참조달 포인터이다.

다른 팁

흠...무엇이 일어나 변경할 경우에는 코드를 위해 무언가가 다음과 같다:

dir.append("/Projection");
sWin.setSetting(dir, static_cast<int>(camera_->getProjectionType()));

에서는 방법 당신이 하고 있는 임시 복사본을 만들고 다음에 바인딩에 대한 참조하 const 는 확인해야합니다.이후,이것에서 참조 QMap 하려고 시도하는 복사는 인수,이 경우에는 것을 암시적 공유 메커니즘의들로 구성되.나는 단지 무슨 잘못 갈 수 있는 거기에...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top