title: Segfault with inheritence and casting
body: <p>I am using an existing <code>C++</code> which looks something like this</p>
  <pre><code>class Geometry {
  public:
      enum {BOX, MESH} type;
      std::string name;
  };
  
  class Mesh : public Geometry {
  public:
      std::string filename;
  };
  
  std::shared_ptr&lt;Geometry&gt; getGeometry() {
      std::shared_ptr&lt;Geometry&gt; geom = std::make_shared&lt;Geometry&gt;();
      geom-&gt;name = &quot;geometry&quot;;
  
      Mesh *mesh = new Mesh();
      mesh-&gt;name = &quot;name&quot;;
      mesh-&gt;filename = &quot;filename&quot;;
      mesh-&gt;type = Geometry::MESH;
      geom.reset(mesh);
  
      return geom;
  }
  </code></pre>
  <p>I need to extend the functionalities provided by these classes, so I have derived these two classes</p>
  <pre><code>#include &lt;memory&gt;
  #include &lt;iostream&gt;
  
  class Geometry {
  public:
      enum {BOX, MESH} type;
      std::string name;
  };
  
  class Mesh : public Geometry {
  public:
      std::string filename;
  };
  
  std::shared_ptr&lt;Geometry&gt; getGeometry() {
      std::shared_ptr&lt;Geometry&gt; geom = std::make_shared&lt;Geometry&gt;();
      geom-&gt;name = &quot;geometry&quot;;
  
      Mesh *mesh = new Mesh();
      mesh-&gt;name = &quot;name&quot;;
      mesh-&gt;filename = &quot;filename&quot;;
      mesh-&gt;type = Geometry::MESH;
      geom.reset(mesh);
  
      return geom;
  }
  
  class GeometryDerived : public Geometry {
  public:
      void consumeGeometry() {
          Geometry geom = static_cast&lt;Geometry&gt;(*this);
          std::cout &lt;&lt; geom.name &lt;&lt; std::endl;
          if(geom.type == Geometry::MESH) {
              Mesh *mesh = static_cast&lt;Mesh*&gt;(&amp;geom);
              std::cout &lt;&lt; mesh-&gt;filename &lt;&lt; std::endl;
              // mesh-&gt;get_output();
          }
      }
  };
  
  class MeshDerived : public Mesh {
  public:
      std::string get_output() {
          return this-&gt;filename;        
      }
  };
  
  
  
  int main(int argc, char** argv)
  {
      std::shared_ptr&lt;Geometry&gt; geom = getGeometry(); // this object is returned by the library
  
      std::shared_ptr&lt;GeometryDerived&gt; geomDerived = std::static_pointer_cast&lt;GeometryDerived&gt;(geom);
      geomDerived-&gt;consumeGeometry();
  
      return 0;
  }
  </code></pre>
  <p>I get a <code>segfault</code> in line (in my actual code, its garbage string)</p>
  <pre><code>std::cout &lt;&lt; mesh-&gt;filename &lt;&lt; std::endl;
  </code></pre>
  <p>though other <code>int</code>s and <code>double</code>s are printed correctly. Even <code>geom.name</code> gets printed correctly. What is going on with strings here? What is the correct way to cast the objects here? Casting the object twice looks ugly. Below is the <code>GDB</code> output</p>
  <pre><code>GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
  Copyright (C) 2020 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;
  This is free software: you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.
  Type &quot;show copying&quot; and &quot;show warranty&quot; for details.
  This GDB was configured as &quot;x86_64-linux-gnu&quot;.
  Type &quot;show configuration&quot; for configuration details.
  For bug reporting instructions, please see:
  &lt;http://www.gnu.org/software/gdb/bugs/&gt;.
  Find the GDB manual and other documentation resources online at:
      &lt;http://www.gnu.org/software/gdb/documentation/&gt;.
  
  For help, type &quot;help&quot;.
  Type &quot;apropos word&quot; to search for commands related to &quot;word&quot;...
  Reading symbols from ./cpp-example...
  (gdb) run
  Starting program: /home/user/cpp-example
  name
  
  Program received signal SIGSEGV, Segmentation fault.
  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383
  383 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
  (gdb) bt
  #0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383
  #1  0x00007ffff7c247b2 in _IO_new_file_xsputn (n=140737488346512, data=0xdb8bbc853a3b3400, f=&lt;optimized out&gt;) at fileops.c:1236
  #2  _IO_new_file_xsputn (f=0x7ffff7d7e6a0 &lt;_IO_2_1_stdout_&gt;, data=0xdb8bbc853a3b3400, n=140737488346512) at fileops.c:1197
  #3  0x00007ffff7c18541 in __GI__IO_fwrite (buf=0xdb8bbc853a3b3400, size=1, count=140737488346512, fp=0x7ffff7d7e6a0 &lt;_IO_2_1_stdout_&gt;) at libioP.h:948
  #4  0x00007ffff7ed2824 in std::basic_ostream&lt;char, std::char_traits&lt;char&gt; &gt;&amp; std::__ostream_insert&lt;char, std::char_traits&lt;char&gt; &gt;(std::basic_ostream&lt;char, std::char_traits&lt;char&gt; &gt;&amp;, char const*, long) ()
     from /lib/x86_64-linux-gnu/libstdc++.so.6
  #5  0x0000555555556858 in GeometryDerived::consumeGeometry (this=0x55555556def0) at ../downcasting.cpp:23
  #6  0x0000555555556513 in main (argc=1, argv=0x7fffffffdec8) at ../downcasting.cpp:53
  
  </code></pre>
  <p><strong>Edit 1:</strong>
  The following changes works fine, but this is not what I want</p>
  <pre><code>int main(int argc, char** argv)
  {
      std::shared_ptr&lt;Geometry&gt; geom = getGeometry();
  
      if(geom-&gt;type == Geometry::MESH) {
          std::shared_ptr&lt;MeshDerived&gt; meshDerived = std::static_pointer_cast&lt;MeshDerived&gt;(geom);
          std::cout &lt;&lt; meshDerived-&gt;filename &lt;&lt; std::endl;
      }
  
      // std::shared_ptr&lt;GeometryDerived&gt; geomDerived = std::static_pointer_cast&lt;GeometryDerived&gt;(geom);
      // geomDerived-&gt;consumeGeometry();
  
      return 0;
  }
  </code></pre>