Pregunta

Actualmente estoy atascado con respecto a Segfaults (a veces sigabrs debido a mallocs) cada vez que intento agregar un QTRing a un QMAP como clave dentro del destructor de Qwidget Class I, creo que tiene algo que ver con la implícita de QString Modelo compartido y alcance.

Tengo un Qwidget que actúa como una ventana secundaria en un MDI, este Qwidget tiene algunas instancias de la ventana de QGLWidget derivadas como niños. En la Sub Ventana hay un QMAP Clase de envoltura que contiene la configuración del archivo del proyecto, cuando se cierra la ventana de la submarina, las llamadas de destructor QWidget :: Deletechildren () que elimina cada una de las visoras. En la ventana Intermitente, la configuración actual se guarda en la configuración de la Submónica, por ejemplo:

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

El Swin.SetSetting () se llama a cada una de las propiedades que deseo ahorrar, 'SWIN' es una referencia a la clase de envoltura QMAP que se elimina al final del destructor de la Subnamen. Todo está bien hasta la llamada SetSetting (), que es solo:

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

Esta configuración funciona bien para la primera ventana gráfica , en la primera llamada SetSetSetting () de la segunda, se produce un Segfault en:

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

¿Estoy viendo una copia profunda falla cuando se pasa mi referencia QString a la QMAP? Si es así, ¿por qué? El QString He creado no ha salido de alcance todavía, ya que el destructor no ha regresado. ¿Y por qué esto fallaría en la segunda ventana y no la primera?

Ocasionalmente obtendré un SIGABRT malloc (): corrupción de memoria en el operador + en la línea SetSetting () del primer ejemplo de código. Pero de nuevo, al comienzo de la destrucción del segundo Puerto, no la primera.

Pido disculpas por la pregunta muy leve, pero hay una gran cantidad de código involucrado en muchas unidades de traducción. ¡Cualquier pista para este problema sería una gran ayuda!

gracias de antemano. Cam


actualización

Cambié mi primer código de código a:

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

como prueba para problemas de alcance. Y lo a veces funciona, y otras veces proporcionan exactamente el mismo error; Por lo tanto, presumiblemente, el montón de Qstring está siendo destruido, solo depende de si su ubicación de memoria se ha sobrescrito o no. Pero esto tampoco tiene sentido, ya que no estoy llamando a Borrarlo, ni estoy cerrando la aplicación (¡solo una ventana de MDI)!


más código

Swin se crea en el montón cuando se instanela una nueva subvange. Se lleva al destructor de la clase de visor como referencia de un método desde mi subvange:

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

sy_proych es (actualmente) una clase de envoltura simple para QMAP. My Complete WiegPort Base Class Destructor es este (falla aquí, no en la clase derivada):

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

Después de usar el Memcheck de Valgrind, descubrí numerosas entradas que se parecían similares a mi stacktrace. Nunca lo ha usado antes, todavía estoy descifrando, pero es este dicho que se ha eliminado mi clase SY_PROJECT (WRAPPER para QMAP) después de la llamada SetSetTing () dejando QMAP con una referencia no válida?

==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)

¿Fue útil?

Solución

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.

Otros consejos

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...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top