title: QString errors when copying into QMap. Scope issue?
body: <p>I'm currently stuck with regards to segfaults (sometimes sigabrts due to bad mallocs) whenever I try add a QString to a QMap as key inside the destructor of QWidget class I have - I think it has something to do with QString's implicit sharing model and scope.</p>
  
  <p>I have a QWidget acting as a sub window in an MDI, this QWidget has a few QGLWidget derived viewport instances as children.  In the sub window there is a QMap&lt; QString, QVariant > wrapper class that contains the project file's settings, when the sub window is closed, it's destructor calls QWidget::deleteChildren() which deletes each of the viewports.  In the viewport destructor the current settings are saved into the sub window's settings, eg:</p>
  
  <pre><code>QString dir = QString( "camera/" ) + name;
  sWin.setSetting( dir + "/Projection",
                   static_cast&lt; int &gt;( camera_-&gt;getProjectionType() ) );
  </code></pre>
  
  <p>The sWin.setSetting() is called for each of the properties I wish to save, 'sWin' is a reference to the QMap wrapper class that is deleted at the end of the sub window destructor.  Everything is fine until the setSetting() call, which is just:</p>
  
  <pre><code>inline void setSetting( const QString&amp; key, QVariant value )
  {
      //  projectSettings_ is a standard QMap&lt; QString, QVariant &gt;.
      projectSettings_.insert( key, value );
  }
  </code></pre>
  
  <p>This setup works fine <em>for the first viewport</em>, at the first setSetting() call of the second, a segfault occurs at:</p>
  
  <pre><code>inline QString::QString(const QString &amp;other) : d(other.d)
  { Q_ASSERT(&amp;other != this); d-&gt;ref.ref(); }
  </code></pre>
  
  <p>Am I seeing a deep copy fail when my QString reference is passed to the QMap?  If so, why?  The QString I created has not gone out of scope yet as the destructor has not returned.  And why would this fail on the second viewport and not the first?</p>
  
  <p>Occasionally I will get a sigabrt <strong>malloc(): memory corruption</strong> in operator+ in the setSetting() line of the first code example .  But again, at the start of the second viewport's destruction, not the first.</p>
  
  <p>I apologise for the very wordy question, but there is a large amount of code involved spread across many translation units.  Any clues for this problem would be a great help! </p>
  
  <p>Thanks in advance.
  Cam</p>
  
  <hr>
  
  <p><strong>Update</strong></p>
  
  <p>I changed my first code sample to:</p>
  
  <pre><code>QString* dir = new QString( "camera/" );
  *dir += name;
  sWin.setSetting( *dir + "/Projection",
                   static_cast&lt; int &gt;( camera_-&gt;getProjectionType() ) );
  </code></pre>
  
  <p>As a test for scope issues. And it <em>sometimes</em> works, and other times gives exactly the same error; so presumably the heap QString is being destroyed, it just depends on whether or not it's memory location has been overwritten.  But this also makes no sense, as I am not calling delete on it, nor am I closing the application (just an MDI sub window)!</p>
  
  <hr>
  
  <p><em><strong>More Code</em></strong></p>
  
  <p>sWin is created on the heap when a new sub window is instantiated.  It is brought into the viewport class' destructor as a reference from a method from my sub window:</p>
  
  <pre><code>inline Sy_project&amp; getProject() { return *project_; }
  </code></pre>
  
  <p>Sy_project is (currently) a simple wrapper class for QMap.  My complete viewport base class destructor is this (it fails here, not in the derived class):</p>
  
  <pre><code>Sy_abstractGLViewport::~Sy_abstractGLViewport()
  {
      //  Write last viewport settings.
      QString name = objectName();
      Sy_project&amp; sWin = projWindow_-&gt;getProject();
      QString dir = QString( "camera/" ) + name;
  
      //  Avoid "taking address of temporary" warning.
      QVector3D pos = camera_-&gt;getPosition();
      QVector3D foc = camera_-&gt;getFocalPoint();
  
      //  Save camera settings.  Dies on first setSetting() call.
      sWin.setSetting( dir + "/Projection",
                       static_cast&lt; int &gt;( camera_-&gt;getProjectionType() ) );
      sWin.setSetting( dir + "/position",
                       QVariant( 84, static_cast&lt; void* &gt;( &amp;pos ) ) );
      sWin.setSetting( dir + "/focalPoint",
                       QVariant( 84, static_cast&lt; void* &gt;( &amp;foc ) ) );
      sWin.setSetting( dir + "/FOV", camera_-&gt;getFOV() );
      sWin.setSetting( dir + "/nearClip", camera_-&gt;getPerspectiveClipRange()[0] );
      sWin.setSetting( dir + "/farClip", camera_-&gt;getPerspectiveClipRange()[1] );
  
      delete camera_;
  }
  </code></pre>
  
  <hr>
  
  <p><strong>Valgrind</strong></p>
  
  <p>After using Valgrind's memcheck I discovered numerous entries that looked similar to my stacktrace.  Having never used it before, I'm still deciphering, but is this saying that my Sy_project class (wrapper for QMap) has been deleted <em>after</em> the setSetting() call leaving QMap with an invalid reference?</p>
  
  <pre><code>==12418== Invalid read of size 4
  ==12418==    at 0x805D872: QMap&lt;QString, QVariant&gt;::detach_helper() (qmap.h:730)
  ==12418==    by 0x805D380: QMap&lt;QString, QVariant&gt;::detach() (in /home/cbamber85/workspace/Syren GUI/Syren)
  ==12418==    by 0x805CDEE: QMap&lt;QString, QVariant&gt;::insert(QString const&amp;, QVariant const&amp;) (qmap.h:537)
  ==12418==    by 0x805CA33: Sy_project::setSetting(QString const&amp;, 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)
  </code></pre>