Reputation: 45
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?
Upvotes: 3
Views: 5413
Reputation: 30489
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.
Upvotes: 5
Reputation: 2207
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.
Upvotes: 2