3

I have a problem sending zmq message built from the pointer to struct, which contains other struct.

The server code:

#include <zmq.hpp> #include <string> #include <iostream> using namespace zmq; using namespace std; struct structB{ int a; string c; }; struct structC{ int z; struct structB b; }; int main() { context_t context(1); socket_t *socket = new socket_t(context,ZMQ_REP); socket->bind("tcp://*:5555"); message_t *request = new message_t(); socket->recv(request); struct structB messageB; messageB.a=0; messageB.c="aa"; struct structC *messageC = new struct structC; messageC->z = 4; messageC->b = messageB; char *buffer = (char*)(messageC); message_t *reply = new message_t((void*)buffer, +sizeof(struct structB) +sizeof(struct structC) ,0); socket->send(*reply); return 0; } 

Client code:

#include <zmq.hpp> #include <iostream> #include <string> using namespace std; using namespace zmq; struct structB{ int a; string c; }; struct structC{ int z; struct structB b; }; int main() { context_t context(1); socket_t *socket = new socket_t(context,ZMQ_REQ); socket->connect("tcp://*:5555"); const char* buffer = "abc"; message_t *request = new message_t((void*)buffer,sizeof(char*),0); socket->send(*request); message_t *reply = new message_t; socket->recv(reply); struct structC *messageC = new struct structC; messageC = static_cast<struct structC*>(reply->data()); cout<<messageC->b.a<<endl;//no crash here struct structB messageB = messageC->b;//Segmentation fault (core dumped) return 0; } 

This program crashes when I try to use string called "c" from structB. It doesn't matter if I try to print it, or assign whole structB as in above example.

Where is the problem? Should I create message_t *reply on server side in different way?

1
  • You have strange mix of C and C++ syntax (In C, structs are separate namespace and require the struct keyword when used, but in C++ they don't. Why do you sometimes use it?) and similarly strange mix of stack and heap allocated objects (Why do you create messageB on stack and messageC on heap? messageC can also be created on stack. And messageB is part of messageC; you don't need a separate instance.) Commented May 15, 2014 at 7:31

2 Answers 2

5

You cannot send string over network as std::string is a container. You can use flexible array member or big size array or write a small class which is serializable (you have to write code by yourself to prepare buffer) to send the data.

When you do struct structB messageB = messageC->b;, pointer members of std::string member embed inside messageC->b might be dereference in copy constructor or std::string which is possibly causing the segmentation fault.

Example of large char array would be:

struct structB{ int a; char c[MAX_LENGTH]; }; 

Later

struct structB messageB; messageB.a=0; strcpy(messageB.c,"aa"); // #include<cstring> or use std::copy from <algorithm> struct structC *messageC = new struct structC; // I guess you want this(not sure) messageC->z = static_cast<int>( sizeof(int) + strlen(messageB) + 1 ); messageC->z = 4; messageC->b = messageB; 

And then

const int length = sizeof(int) /* z */ + sizeof(int) /* a */ + strlen("aa") + 1; zmq::message_t msg (length); memcpy (msg.data (), &messageC, length); socket->send(msg); 

These are some changes required at server side, you need to make similar changes at client side also.

As a side note, your code is very messy, don't deploy it in larger applications before sorting out few things like removal of unnecessary new and properly representing nested structures.

Sign up to request clarification or add additional context in comments.

2 Comments

I would strongly recommend using something like Google Protobuf or Boost.Serialization to handle the serialization. It sounds like overkill for playing around, but even throw-away prototypes often end up being used long past their originally expected lifetime and when it grows large or when it needs to change, good serialization library will help a lot in keeping the code maintainable.
@JanHudec I completely agree with you.
2

Your structures are not POD. Class "string" can't be copied as memory heap. There is a problem.

Use c.c_str() and c.size() to copy in as memory block.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.