title: Boost: De-serializing a custom C++ object passed over ZeroMQ pull socket
body: <p>The text I am writing here is a follow up problem that I opened up earlier in another thread at <a href="https://stackoverflow.com/questions/14480161/boost-serializing-de-serializing-a-custom-c-object-passed-over-zeromq-pull-so">Boost: Serializing/De-serializing a custom C++ object passed over ZeroMQ pull socket</a>. The compilation problems in the earlier thread have been resolved by using a textarchive type rather than binaryarchive but now I experience a runtime problem when de-serializing. I repeat the earlier text here with a new problem statement for your convenience. I am relatively new to C++ realm and appreciate any further help.</p>
  
  <p><strong>Description:</strong></p>
  
  <p>I have a C++ class named <strong>GenericMessage</strong> which simply holds an id and data as its members (See code snippet 2 below - GenericMessage.hxx). My intention is to serialize an instance of this class and send it via a ZeroMQ socket which implements the push pattern. </p>
  
  <p>The serialization and sending task has been implemented in <strong>class ZMQHandler</strong> (see sendToBE function) which is placed in a header file name ZMQHandler.hxx shown in the <strong>code snippet 3</strong> below. This class is instantiated by <strong>TestFE.cxx</strong> shown in <strong>the 4rd code snippet</strong> below.</p>
  
  <p>The receiving and de-serialization of the GenericMessage instance is implemented in <strong>TestBE.cxx</strong>  available in the <strong>5th code snippet</strong> below. My intention is to receive the GenericMessage instance over the ZMQ socket (i.e. pull socket), de-serialize it and then print its members to standard output. </p>
  
  <p><strong>Problem Statement:</strong></p>
  
  <p>When I run the receiver (i.e. TestBE.cxx) I verified here that I can transfer data from TestFE.cxx to TEstBE.cxx over the ZMQ socket. However, I got an exception shown in the 1st code snippet below exactly when I attempt to de-serialize the input archive at line 28 in TestBE.cxx (see the 5th code snippet very below, line 28 has been marked). </p>
  
  <p>Is there something I am missing in this de-serialization procedure implemented in TestBE.cxx in code snippet 5? Why do you think I am getting this exception? Could it be that I am missing st in the serialization procedure implemented in ZMQHandler.cxx (code snippet 3 - function sendToBE). Thanks in advance. </p>
  
  <p><strong>CODE SNIPPET 1 GDB OUTPUT &amp; backtrace</strong></p>
  
  <pre><code>$ gdb TestBE 
  GNU gdb (GDB) 7.5-ubuntu
  .....
  (gdb) r
   Starting program: /TestBE 
   [Thread debugging using libthread_db enabled]
   Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
   [New Thread 0xb7c12b40 (LWP 16644)]
   [New Thread 0xb7411b40 (LWP 16645)]
   Connecting to FE...
  </code></pre>
  
  <p><strong>!!!!!!!!!!!!!!!!!!!!HERE BEGINS!!!!!!!!!!!!!!!!!!!!!!!!!!!</strong></p>
  
  <pre><code> **CHAR [22 serialization::archive 9 0 1 0
   0 1 12 Hello there!]
   terminate called after throwing an instance of 'std::logic_error'
   what():  basic_string::_S_construct null not valid**
  </code></pre>
  
  <p><strong>!!!!!!!!!!!!!!!!!!!!HERE END !!!!!!!!!!!!!!!!!!!!!!!!!!!</strong></p>
  
  <pre><code> Program received signal SIGABRT, Aborted.
   0xb7fdd424 in __kernel_vsyscall ()
   (gdb) bt
   #0  0xb7fdd424 in __kernel_vsyscall ()
   #1  0xb7c7a1df in raise () from /lib/i386-linux-gnu/libc.so.6
   #2  0xb7c7d825 in abort () from /lib/i386-linux-gnu/libc.so.6
   #3  0xb7e608ad in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/i386-  linux-gnu/libstdc++.so.6
   #4  0xb7e5e4f3 in ?? () from /usr/lib/i386-linux-gnu/libstdc++.so.6
   #5  0xb7e5e52f in std::terminate() () from /usr/lib/i386-linux-gnu/libstdc++.so.6
   #6  0xb7e5e825 in __cxa_rethrow () from /usr/lib/i386-linux-gnu/libstdc++.so.6
   #7  0x0804c1d4 in    boost::archive::detail::pointer_iserializer&lt;boost::archive::text_iarchive,    GenericMessage&lt;std::string&gt; &gt;::load_object_ptr (this=0x8054444, ar=..., 
   x=@0x805cb40: 0x805cb50, file_version=0) at    /usr/include/boost/archive/detail/iserializer.hpp:327
   #8  0xb7f3839d in boost::archive::detail::basic_iarchive::load_pointer(void*&amp;,  boost::archive::detail::basic_pointer_iserializer const*,  boost::archive::detail::basic_pointer_iserializer const* (*) (boost::serialization::extended_type_info const&amp;)) () from  /usr/lib/libboost_serialization.so.1.49.0
   #9  0x0804bea9 in    boost::archive::detail::load_pointer_type&lt;boost::archive::text_iarchive&gt;::invoke&lt;GenericMes     sage&lt;std::string&gt;*&gt; (ar=..., t=@0xbfffef70: 0xbfffeff8)
   at /usr/include/boost/archive/detail/iserializer.hpp:524
   #10 0x0804be55 in boost::archive::load&lt;boost::archive::text_iarchive,                                  GenericMessage&lt;std::string&gt;*&gt; (ar=..., t=@0xbfffef70: 0xbfffeff8)
   at /usr/include/boost/archive/detail/iserializer.hpp:592
   #11 0x0804be36 in   boost::archive::detail::common_iarchive&lt;boost::archive::text_iarchive&gt;::load_override&lt;Gener icMessage&lt;std::string&gt;*&gt; (this=0xbfffef84, t=@0xbfffef70: 0xbfffeff8)
    at /usr/include/boost/archive/detail/common_iarchive.hpp:66
   #12 0x0804be14 in  boost::archive::basic_text_iarchive&lt;boost::archive::text_iarchive&gt;::load_override&lt;GenericMe ssage&lt;std::string&gt;*&gt; (this=0xbfffef84, t=@0xbfffef70: 0xbfffeff8)
    at /usr/include/boost/archive/basic_text_iarchive.hpp:65
   #13 0x0804bdf2 in boost::archive::text_iarchive_impl&lt;boost::archive::text_iarchive&gt;::load_override&lt;GenericMes sage&lt;std::string&gt;*&gt; (this=0xbfffef84, t=@0xbfffef70: 0xbfffeff8)
    at /usr/include/boost/archive/text_iarchive.hpp:82
   #14 0x0804bcec in      boost::archive::detail::interface_iarchive&lt;boost::archive::text_iarchive&gt;::operator&gt;&gt; &lt;GenericMessage&lt;std::string&gt;*&gt; (this=0xbfffef84, t=@0xbfffef70: 0xbfffeff8)
   at /usr/include/boost/archive/detail/interface_iarchive.hpp:60
   #15 0x0804b2a1 in main () at TestBE.cxx:28
  </code></pre>
  
  <p><strong>CODE SNIPPET 2 (GenericMessage.hxx)</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;sstream&gt;
  #include &lt;boost/serialization/serialization.hpp&gt;
  #include &lt;boost/archive/text_oarchive.hpp&gt;
  #include &lt;boost/archive/text_iarchive.hpp&gt;
  
  template &lt;class T&gt;
  class GenericMessage {
  public:
    GenericMessage(): 
      beId(-1), 
      data(NULL)
    {}
  
    GenericMessage(int id, T msg): 
      beId(id), 
      data(msg)
    {}
  
    ~GenericMessage(){}
  
    T getData()
    {
      return data;
    }
  
  
    std::string toString()
    {
       std::ostringstream ss;
       ss &lt;&lt; getBeId();
       std::string ret =  ss.str();
  
      return ret;
    }
  
    void setBeId(int id)
    {
      beId = id;
    }
  
    int getBeId()
    {
      return beId;
    }
  
  
    private:
        friend class boost::serialization::access;
  
    int beId;
    T data;
  
  
    template &lt;class Archive&gt;
    void serialize(Archive &amp; ar, const unsigned int version)
    {
        ar &amp; beId;
        ar &amp; data;
    }
  
   };
  </code></pre>
  
  <p><strong>CODE SNIPPET 3 (ZmqHandler.hxx)</strong></p>
  
  <pre><code>#include "zmq.hpp"
  #include "GenericMessage.hxx"
  #include &lt;unistd.h&gt;
  #include &lt;cassert&gt;
  
  template &lt;class A&gt;
  class ZmqHandler {
  public:
  
  ZmqHandler():
  mContext(1),
  mOutbHandlerSocket(mContext, ZMQ_PUSH)
  {    
      mOutbHandlerSocket.bind ("tcp://*:5555");       
  }
  
  
  ~ZmqHandler() {}
  
  void sendToBE(GenericMessage&lt;A&gt; *theMsg)
  {
     std::ostringstream archive_stream;
     boost::archive::text_oarchive archive(archive_stream);
  
     try
     {
       archive &lt;&lt; theMsg;
     } catch (boost::archive::archive_exception&amp; ex) {
        std::cout &lt;&lt; "Archive Exception during deserializing:" &lt;&lt; std::endl;
        std::cout &lt;&lt; ex.what() &lt;&lt; std::endl;           
     } catch (int e) {
         std::cout &lt;&lt; "EXCEPTION " &lt;&lt; e &lt;&lt; std::endl; 
     }
  
     std::string outbound_data_ = archive_stream.str();
     const char * buf = outbound_data_.c_str();    
     int len = strlen((const char*)buf);
     std::cout &lt;&lt; "LENGTH [" &lt;&lt; len &lt;&lt; "]" &lt;&lt; std::endl;
  
     zmq::message_t msgToSend(len);
  
     memcpy ((char *) msgToSend.data(), buf, len);
  
     if(memcmp((char *) msgToSend.data(), buf, len) != 0)
     {
       std::cout &lt;&lt; "memcpy error!" &lt;&lt; std::endl;
     }
  
     mOutbHandlerSocket.send(msgToSend);
     std::cout &lt;&lt; "SENT request: [" &lt;&lt; theMsg-&gt;toString() &lt;&lt; "]" &lt;&lt; std::endl;
   }   
  
    private:  
       zmq::context_t mContext;
       zmq::socket_t mOutbHandlerSocket;         
   };
  </code></pre>
  
  <p><strong>CODE SNIPPET 4 (TestFE.cxx)</strong></p>
  
  <pre><code>  #include "ZmqHandler.hxx"
  
    int main ()
    {
       ZmqHandler&lt;std::string&gt; zmqHandler;
       int counter = 1;
  
       while(1)
       {  
          std::string data = "Hello there!\0";
          GenericMessage&lt;std::string&gt; msg(counter, data);
          zmqHandler.sendToBE(&amp;msg);
          counter++;
         sleep(1);
        }
  
      return 0;
   }
  </code></pre>
  
  <p><strong>CODE SNIPPET 5 (TestBE.cxx)</strong></p>
  
  <pre><code> #include "zmq.hpp"
   #include "GenericMessage.hxx"
   #include &lt;fstream&gt;
  
   int main ()
   {
      //  Prepare our context and socket
      zmq::context_t context (1);
      zmq::socket_t socket (context, ZMQ_PULL);
  
      std::cout &lt;&lt; "Connecting to FE..." &lt;&lt; std::endl;
      socket.connect ("tcp://localhost:5555");
  
      while(1){
         zmq::message_t reply;
         socket.recv (&amp;reply);
  
         const char *buf = static_cast&lt;const char*&gt;(reply.data());
         std::cout &lt;&lt; "CHAR [" &lt;&lt; buf &lt;&lt; "]" &lt;&lt; std::endl;
  
         std::string input_data_(buf); 
         std::istringstream archive_stream(input_data_);
         boost::archive::text_iarchive archive(archive_stream);
         GenericMessage&lt;std::string&gt; *theMsg;
  
         try
         {
         /* !!!!!!!!!! LINE 28 is the following !!!!!!!!!!*/
           archive &gt;&gt; theMsg;
         } catch (boost::archive::archive_exception&amp; ex) {
            std::cout &lt;&lt; "Archive Exception during deserializing:" &lt;&lt; std::endl;
            std::cout &lt;&lt; ex.what() &lt;&lt; std::endl;           
         } catch (int e) {
            std::cout &lt;&lt; "EXCEPTION " &lt;&lt; e &lt;&lt; std::endl; 
         }
  
         std::cout &lt;&lt; "ID" &lt;&lt; theMsg-&gt;getBeId() &lt;&lt; std::endl; 
         std::cout &lt;&lt; "Data" &lt;&lt; theMsg-&gt;getData() &lt;&lt; std::endl; 
  
       }
  
      return 0;
     }
  </code></pre>