I have to send and receive dynamic data using a SysV message queue for a university project.
The length of the data is transmitted in a separate message, size is therefor already known.
And this is how I try to receive the data. I have to admit that I’m not a C++ specialist, especially when it comes to memory allocation.
struct {
long mtype;
char *mdata;
} msg;
msg.mdata = (char *)malloc(size * sizeof(char));
msgrcv(MSGQ_ID, &msg, size, MSG_ID, 0);
The problem seems to be the malloc call, but I don’t know how to do this right.
EDIT
What I try is to have a some sort of read method in a OO wrapper around the message queues. I’d like to read the data in the message queue into a char[] or a std::string. What I have now looks (simplified) like this.
bool Wrapper::read(char *data, int length)
{
struct Message {
long mtype;
std::string mdata;
};
Message msg;
msg.mdata = std::string(size, '\0');
if(msgrcv(MSGQ_ID, &msg, size, MSG_ID, 0) < 0)
{
return false;
}
memcpy(data, msg.mdata.c_str(), msg.mdata.size());
return true;
}
All I get is segmentation faults or completely corrupt data (although this data sometimes contains what I want).
You can’t pass a pointer to a structure that contains a
std::stringmember tomsgrcv, this violates the interface contract.The second parameter passed to
msgrcvneeds to point to a buffer with sufficient space to store a ‘plain’ C struct of the formstruct { long mtype; char mdata[size]; };where size is the third parameter tomsgrcv.Unfortunately, determining the size of this buffer might depend on
sizedue to possible alignment issues but you have to assume that it doesn’t on a system that provides this sort of interface. You can use the standardoffsetofmacro to help determine this size.As a
vectorstores its components contiguously, once you know the size of the buffer, you can resize avectorofcharand use this to hold the buffer. Using avectorrelieves you of the obligation tofreeordelete[]a buffer manually.You need to do something like this.
To go the other way, you just have to pack the data into a
structhack compatible data array as required by the msgsnd interface. As others have pointer out, it’s not a good interface, but glossing over the implementation defined behaviour and alignment concerns, something like this should work.e.g.