I need to do some high performance c++ stuff and that is why I need to avoid copying data whenever possible.
Therefore I want to directly assign a string buffer to a zmq::message_t object without copying it. But there seems to be some deallocation of the string which avoids successful sending.
Here is the piece of code:
for (pair<int, string> msg : l) {
comm_out.send_int(msg.first);
comm_out.send_int(t_id);
int size = msg.second.size();
zmq::message_t m((void *) std::move(msg.second).data(), size, NULL, NULL);
comm_out.send_frame_msg(m, false); // some zmq-wrapper class
}
How can I avoid that the string is deallocated before the message is send out? And when is the string deallocated exactly?
Regards
I think that
zmq::message_t m((void *) std::move(msg.second).data()...
is probably undefined behaviour, but is certainly the cause of your problem. In this instance,std::move
isn't doing what I suspect you think it does.The call to
std::move
is effectively creating an anonymous temporary of a string, moving the contents ofmsg.second
into it, then passing a pointer to that temporary data into themessage_t
constructor. The 0MQ code assumes that pointer is valid, but the temporary object is destroyed after the constructor ofmessage_t
completes - i.e. before you callsend_frame
.Zero-copy is a complicated matter in 0mq (see the 0MQ Guide) for more details, but you have to ensure that the data that hasn't been copied is valid until 0MQ tells you explicitly that it's finished with it.
Using C++ strings in this situation is hard, and requires a lot of thought. Your question about how to "avoid that the string is deallocated..." goes right to the heart of the issue. The only answer to that is "with great care".
In short, are you sure you need zero-copy at all?