title: C++ bi-directional association: object access with smart pointers seems to corrupt the instance
body: <p>I had a bi-directional object association implemented with raw pointers and it worked without flaw. Then I decided to <strong>refactor my code with smart pointers</strong> and all of a sudden <strong>a string member</strong> (<em>depName</em>) of one of the classes (<em>Department</em>) is <strong>no longer accesssible after object initialization</strong>. I checked if the parameter gets passed correctly and in the constructor everything is ok. The member gets the intended value. But afterwards it is no longer accessible and <strong>in addition</strong> to that <strong>the code that ran smoothly before, now crashes</strong>. I have no clue why. </p>
  
  <p>EDIT: The same seems to be happening to the string variable name used for in the Manager class. END EDIT</p>
  
  <ul>
  <li>The code compiles without errors or even warnings.</li>
  <li>I'm working with qt creator 3.3.0 and mingw compiler 5.4.0</li>
  <li>The System claims there is a "Segmentation fault".</li>
  </ul>
  
  <p>This is my code (sorry it's a lot - I reduced it as much as I dared):</p>
  
  <p>in the <strong>header files</strong>:</p>
  
  <pre><code>    class Manager;
      class Department
      {
      private:
          string depName;
          shared_ptr&lt;Manager&gt; head;
          vector &lt;shared_ptr&lt;Manager&gt;&gt; depMembers;
      public:
          Department(string depName, shared_ptr&lt;Manager&gt; head);
          virtual ~Department();
          string getDepName() const;
          void setDepName(const string &amp;value);
          void addMember(shared_ptr&lt;Manager&gt; newMember);
          void removeMember(shared_ptr&lt;Manager&gt; who);
          const shared_ptr&lt;Manager&gt;getHead() const;
          void setHead(shared_ptr&lt;Manager&gt;value);
          double sumOfIncome();
          void show();
      };
      //--------------------------------
      class Department;
      class  Manager
      {
          private:
              string name;
              float salary;
              float bonus;//Bonus ist ein Prozentsatz
              weak_ptr&lt;Department&gt; myDepartment;
      //        Department * myDepartment; //With this raw pointer the code still worked*
          public:
              Manager(string, float, float);
              virtual ~Manager();
              float income()const ;
              string toString()const ;
              double calcBonus() const;
              shared_ptr&lt;Department&gt; getMyDepartment() const;
              void setMyDepartment(shared_ptr&lt;Department&gt; abt);
              float getSalary() const;
              string getName() const;
      };
  </code></pre>
  
  <p>in the <strong>cpp files</strong>:
  department.cpp</p>
  
  <pre><code>    //---------------------------------------------------
      Department::Department(string depName, shared_ptr&lt;Manager&gt;head)
          :depName(depName),head(nullptr)
      {
          this-&gt;setHead(head);
          cout &lt;&lt; "\nIn constructor parameter depName: " + depName;
          cout &lt;&lt; "\n instancevariable " + this-&gt;depName &lt;&lt; endl;
      }
      //--------------------------------
      Department::~Department()
      {}
      //--------------------------------
      string Department::getDepName() const
      {
          return this-&gt;depName;
      }
      //--------------------------------
      void Department::setDepName(const string &amp;value)
      {
          depName = value;
      }
      //--------------------------------
      void Department::addMember(shared_ptr&lt;Manager&gt; newMember)
      {
          depMembers.push_back(newMember);
      }
      //--------------------------------
      void Department::removeMember(shared_ptr&lt;Manager&gt; who)
      {
          vector&lt;shared_ptr&lt;Manager&gt;&gt;::iterator itMember = depMembers.begin();
          //Iterator must be dereferenced to access data
          while( *itMember != who){
              itMember++;
          }
          if( *itMember == who)
              depMembers.erase( itMember);
      }
      //--------------------------------
      const shared_ptr&lt;Manager&gt; Department::getHead() const
      {
          return head;
      }
      //--------------------------------
      void Department::setHead(shared_ptr&lt;Manager&gt;value)
      {
          if( head != nullptr &amp;&amp; head-&gt;getMyDepartment()!= nullptr)
              head-&gt;setMyDepartment(nullptr);//department of old head is deleted
  
          //new head of department assigned
          head = value;
          //bidirektionaler access
          if(head !=nullptr)
              head-&gt;setMyDepartment( shared_ptr&lt;Department&gt;(this));
      }
      //--------------------------------
      double Department::sumOfIncome()
      {
          double sum = 0;
          for(unsigned int i=0; i &lt; depMembers.size(); i++){
              sum += depMembers[i]-&gt;getSalary() ;
          }
          return sum;
      }
      //--------------------------------
      void Department::show()
      {
          cout &lt;&lt;"----------------" &lt;&lt; endl;
          cout &lt;&lt; "Department: " &lt;&lt; this-&gt;depName &lt;&lt; " run by " &lt;&lt; head-&gt;getName()&lt;&lt;endl;
          cout &lt;&lt;"----------------" &lt;&lt; endl;
          cout &lt;&lt; "Members: " &lt;&lt; endl;
          cout &lt;&lt;"----------------" &lt;&lt; endl;
          cout &lt;&lt; head-&gt;toString() &lt;&lt; endl;
          for( unsigned int i=0; i &lt; depMembers.size() ; i++){
              cout &lt;&lt;"----------------" &lt;&lt; endl;
              cout &lt;&lt; depMembers[i]-&gt;toString()&lt;&lt; endl;
          }
          cout &lt;&lt;"----------------" &lt;&lt; endl;
      }
  </code></pre>
  
  <p>manager.cpp</p>
  
  <pre><code>    //---------------------
      float Manager::getSalary() const
      {
          return salary;
      }
      //----------------------------------
      string Manager::getName() const
      {
          return name;
      }
      //----------------------------------
      Manager::Manager(string n, float s, float bon)
          :name(n),salary(s), bonus(bon)
      {}
      //----------------------------------
      Manager::~Manager(){}
      //----------------------------------
      float Manager::income()const
      {
          return (salary + calcBonus() );
      }
      //----------------------------------
      string Manager::toString() const
      {
          stringstream ss;
          ss &lt;&lt; name &lt;&lt; "\n heads the department ";
          shared_ptr&lt;Department&gt; dep = myDepartment.lock();
          if( dep !=nullptr)
              ss&lt;&lt; dep-&gt;getDepName();
          else ss &lt;&lt; " NONE ";
          ss &lt;&lt; "\nBonus: " &lt;&lt; calcBonus();
          ss &lt;&lt; "\nIncome: " &lt;&lt; income();
          return ss.str();
      }
      //----------------------------------
      double Manager::calcBonus()const
      {
          shared_ptr&lt;Department&gt; dep = myDepartment.lock();
          if(dep != nullptr)
              return dep-&gt;sumOfIncome()* bonus;
          else
              return 0;
      }
  
      //----------------------------------
      shared_ptr&lt;Department&gt; Manager::getMyDepartment() const
      {
      //    if( !meineAbteilung-&gt;expired())
          return myDepartment.lock();
      }
      //----------------------------------
      void Manager::setMyDepartment( shared_ptr&lt;Department&gt; dep)
      {
          myDepartment = dep;
      }
      //----------------------------------
  </code></pre>
  
  <p>test run:</p>
  
  <pre><code>    int main(){
          shared_ptr&lt;Department&gt; itDepartment 
              = make_shared&lt;Department&gt;("IT",make_shared&lt;Manager&gt;("Julia", 66066, 0.15));
  
          itDepartment-&gt;show();
          return 0;
      }
  </code></pre>