我在发送从指向struct的指针构建的zmq消息时遇到问题,该指针包含其他结构。
服务器代码:
#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;
}
客户代码:
#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;
}
当我尝试使用structB中名为“c”的字符串时,此程序崩溃。如果我尝试打印它,或者如上例所示分配整个structB并不重要。
问题出在哪里?我应该以不同的方式在服务器端创建message_t *回复吗?
答案 0 :(得分:3)
您无法通过网络发送string,因为std::string
是一个容器。您可以使用flexible array member或大尺寸数组或编写一个小类serializable(您必须自己编写代码来准备缓冲区)以发送数据。
执行struct structB messageB = messageC->b;
时,嵌入在messageC-&gt; b中的std::string
成员的指针成员可能在复制构造函数或std::string
中取消引用,这可能导致分段错误。
大字符数组的示例是:
struct structB{
int a;
char c[MAX_LENGTH];
};
后来
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;
然后
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);
这些是服务器端所需的一些更改,您还需要在客户端进行类似的更改。
作为旁注,您的代码非常混乱,在排除诸如删除不必要的new
和正确表示嵌套结构之类的一些事情之前,不要将它部署在更大的应用程序中。
答案 1 :(得分:2)
你的结构不是POD。类“字符串”不能复制为内存堆。有一个问题。
使用c.c_str()和c.size()作为内存块进行复制。