今天写了一段很 sb 的代码:
socket_.async_read_some(
boost::asio::buffer(recv_buffer_),
[&, this](boost::system::error_code ec, std::size_t bytes_transferred) {
if (!ec) {
auto iter =
std::find(std::begin(recv_buffer_),
std::begin(recv_buffer_) + bytes_transferred, '\n');
std::string recvd;
std::copy(std::begin(recv_buffer_), iter, std::begin(recvd));
….
});
这段代码本意很简单, 就是想把收到的数据拷贝一份到 recvd 里, 然而却未能得到预期的结果 --- 实际的结果是 recvd 为空.
这段代码里 recv_buffer_ 是个 std::array<char, N>, 泛型算法 std::copy 的实现原理如下:
template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last,
OutputIt d_first)
{
while (first != last) {
*d_first++ = *first++;
}
return d_first;
}
我 std::begin 获得 recvd 的初始迭代器, 然而我忽略了 recvd 是未初始化的 string, 对于未初始化的 recvd 来说, 初始迭代器和结束迭代器是相等的, 也就是说, recvd 的初始迭代器在进入 copy 方法的第一步就执行了越界操作, 当迭代器越界会怎样呢? 答案是 "未定义行为": https://stackoverflow.com/questions/1057724/what-happens-if-you-increment-an-iterator-that-is-equal-to-the-end-iterator-of-a/9113774
如此一来, recvd 为空也就不奇怪了.