记一个 std::string 未初始化引发的泛型算法拷贝失败问题

Words
204
Reading
1 min
Listen
Play
8y

今天写了一段很 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 为空也就不奇怪了.

记一个 std::string 未初始化引发的泛型算法拷贝失败问题 | Ecency