質問

現在、Segfaults(QWidgetクラスのデストラクターのデストラクタのデストラクタのデストラクタの中のキーとして追加するたびに、Segfaults(Bad MallocsによるSigabrts)に関しては、QSstringの鍵の中の鍵としてqstringを追加してみましょう。モデルとスコープを共有する。

QWIDGETがMDIのサブウィンドウとして機能している場合、このQWIDGETには、子供として数QGLWidget派生ビューポートインスタンスがあります。サブウィンドウでは、プロジェクトファイルの設定を含むQMAP ラッパークラスがあります。サブウィンドウがクローズされている場合、それぞれのビューポートを削除するQwidget :: DeleteChildren()はデストラクタです。 ViewPortデストラクタで現在の設定はサブウィンドウの設定に保存されます。

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

swin.setsetting()は、保存したいプロパティごとに呼び出されます。 'swin'は、サブウィンドウデストラクタの末尾で削除されるQMapラッパークラスへの参照です。 SetSetting()呼び出しが正しいです。

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

このセットアップは、最初のビューポートの最初のビューポートには、2番目のsetsetting()呼び出しで、SegFaultが:

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

私は私のQSTRING参照がQMapに渡されたときに、ディープコピーが失敗しますか?もしそうなら、なぜ?作成したQSTRINGは、デストラクタが返却されていないため、まだ範囲外になりません。そして、これは最初のビューポートで失敗するのでしょうか。

時折私はSigaBrt Malloc()を取得します。最初のコード例のsetSetting()行の演算子のメモリ破損。しかし、再び、2番目のビューポートの破壊の開始時に、最初のものではありません。

私は非常に単語の質問をお詫び申し上げますが、多くの翻訳単位にわたって広がる大量のコードが含まれています。この問題のための手がかりはすばらしい助けになるでしょう!

事前にありがとう。 カム


更新

私の最初のコードサンプルを次のように変更しました:

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

スコープの問題のテストとして。そしてそれは時々が機能し、他の時間はまったく同じエラーを与えます。だからおそらくヒープQStringは破壊されていますが、メモリの場所が上書きされたかどうかはただ依存します。しかし、これはそれに削除を呼んでいないので、これも意味をなさない、私はアプリケーションを閉じていません(MDIサブウィンドウだけ)!


コード

swinは、新しいサブウィンドウがインスタンス化されたときにヒープ上に作成されます。それは私のサブウィンドウからのメソッドからの参照としてViewPortクラスのデストラクタに持ち込まれます:

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 for QMapのラッパー)が削除されたことはの後、qmapを無効なリファレンスで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)
.

役に立ちましたか?

解決

I think the Sy_project object your pointer and therefore references are pointing to is already destroyed by the time the destructor of Sy_abstractGLViewport is called. If you look into the valgrind listing, the destructor of Sy_project is called before the destructor of Sy_abstractGLViewport.

So when you call inline Sy_project& getProject() { return *project_; } within the Sy_abstractGLViewport destructor, you're dereferencing a dangling pointer.

他のヒント

Hum... What happens if you change your code for something like this:

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

In the way you are doing a temporary copy is create and then bound to a reference-to-const, which should be ok. Afterwards, from this reference QMap will attempt to copy the argument, in this case, going through the implicit sharing mechanism of QString. I'm just wondering what could go wrong in there...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top