9

这个程序(它已经从一个更大的程序中缩小了)在windows 7下以vs2008 Release(Win32)模式编译后总是崩溃。我对汇编代码不熟悉,不知道这是编译器或boost :: ends_with的错误或 boost::asio::buffers_iterator。它可以在 Ubuntu 中用 g++ 编译和执行,没有任何问题。

人们说这不太可能是编译器的错误,但是当以调试模式(或禁用优化)编译时,问题确实消失了。

我已经被这个问题困扰了好几个小时。任何帮助表示赞赏。提前致谢。

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/algorithm/string.hpp>

typedef boost::asio::buffers_iterator<boost::asio::const_buffers_1> iterator_t;
typedef boost::iterator_range<iterator_t> range_t;
static const std::string LINE_END_MARK = "\r\n";

int main(int argc, char* argv[])
{
    boost::asio::streambuf _buf;
    std::ostream os(&_buf);
    os<<"END\r\n";

    iterator_t cursor = boost::asio::buffers_begin(_buf.data());
    iterator_t end = boost::asio::buffers_end(_buf.data());

    std::ostream_iterator<char> it(std::cout," ");
    std::copy(LINE_END_MARK.begin(), LINE_END_MARK.end(), it);

    range_t r(cursor, end);
    if(!boost::ends_with(r, LINE_END_MARK))
        return 0;
    return 1;
}
4

2 回答 2

1

编辑:我误读了代码,对不起。

您的光标和结束迭代器指向无效内存。您修改了在复制到输出迭代器期间重新分配的底层流缓冲区。asio streambuf 允许您出于性能原因访问原始内存,但需要注意的是您必须担心这样的事情。

调试和释放将改变分配和释放的行为方式,涉及分配块的底层大小以及内存如何被隔离、保护、初始化、对齐等。

在复制操作之后构造迭代器以解决您的问题。

于 2012-11-11T20:12:20.560 回答
1

它不起作用,因为 'range_t r(cursor, end)' 是“缓冲区”范围而不是字符范围。因此,您将缓冲区指针列表与 LINE_END_MARK 中的每个字符进行比较。

如果在 win32 下的发布模式下崩溃,因为在 Windows 中,您最终会取消引用导致崩溃的空指针。

boost asio 有多个缓冲区的概念,但目前并没有真正使用。如果您查看实现是否仅真正使用 'const_buffers_1' 或 'mutable_buffers_1' 这基本上是 1 个缓冲区的列表。

我假设您想比较缓冲区的内容,而不是缓冲区范围的列表。

所以你想做这样的事情:

typedef boost::iterator_range<const char*> range_t;
range_t r(boost::asio::buffer_cast<const char*>(_buf.data()), boost::asio::buffer_cast<const char*>(_buf.data()) + boost::asio::buffer_size(_buf.data()));
if(!boost::ends_with(r, LINE_END_MARK))
    return 0;
return 1;
于 2012-11-12T10:21:08.793 回答