Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost ASIO scatter-gather I/O causes mysterious memory errors

I'd like to send multiple strings through TCP without combining them into one big string first, and as I understand ASIO's scatter-gather I/O interface can do this. However, I must be doing something wrong because my implementation keeps running into memory errors. The snippet below (compilable and runnable) returns a garbled string when I telnet localhost 11211:

#include <vector>
#include <string>
#include <boost/asio.hpp>

using namespace std;
using namespace boost::asio;
using namespace boost::asio::ip;

int main() {
    io_service service;
    tcp::acceptor acceptor(service, tcp::endpoint(tcp::v4(), 11211));
    tcp::socket sock(service);
    acceptor.accept(sock);
    if (!acceptor.is_open()) return 1;
    string s = "this is a really long string";
    vector<const_buffer> vec;
    vec.push_back(buffer(s));
    write(sock, buffer(vec));
}

However, it works fine when I do write(sock, buffer("this is a really long string")). What am I missing here?

like image 613
int3 Avatar asked Mar 12 '13 08:03

int3


1 Answers

The last line should be:

write(sock, vec);

Otherwise it's not "scatter-gather", because buffer free function always returns mutable_buffers_1, i.e. a single buffer. In your case the following buffer overload gets called:

template <typename PodType, typename Allocator>
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
{
  return mutable_buffers_1(mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)));
}

Since your vector is not a "vector of POD", it's treated incorrectly.

like image 118
Igor R. Avatar answered Sep 28 '22 11:09

Igor R.