C++ 编译器或boost库的Bug?

C++ 编译器或boost库的Bug?,c++,visual-c++,boost,boost-asio,C++,Visual C++,Boost,Boost Asio,在Windows7下以vs2008发行版(Win32)模式编译后,此程序(已从较大的程序缩小)总是会崩溃。我不熟悉汇编代码,也不知道这是编译器或boost::ends_和boost::asio::buffers_迭代器的错误。它可以在Ubuntu中用g++编译和执行,没有任何问题 人们说这不太可能是编译器的错误,但当以调试模式编译(或禁用优化)时,问题确实消失了 这个问题困扰了我好几个小时了。感谢您的帮助。提前谢谢 #include <iostream> #include <s

在Windows7下以vs2008发行版(Win32)模式编译后,此程序(已从较大的程序缩小)总是会崩溃。我不熟悉汇编代码,也不知道这是编译器或boost::ends_和boost::asio::buffers_迭代器的错误。它可以在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;
}
#包括
#包括
#包括
#包括
typedef boost::asio::buffers\u iterator\u t;
typedef boost::迭代器范围;
静态常量std::字符串行\u END\u MARK=“\r\n”;
int main(int argc,char*argv[])
{
boost::asio::streambuf\u buf;
标准::奥斯特雷姆操作系统(&_buf);

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

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

Debug和release将改变分配和解除分配的行为方式,包括分配块的底层大小以及内存的防护、保护、初始化和对齐方式等


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

它不起作用,因为“范围\u t r(光标,结束)”是一个“缓冲区”范围,而不是一个字符范围。因此,您将缓冲区指针列表与第\u结束\u行中的每个字符进行比较

如果由于在windows中取消引用导致崩溃的空指针而在win32下的发布模式下崩溃

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;
typedef boost::迭代器范围;
范围(boost::asio::buffer_cast(_buf.data())、boost::asio::buffer_cast(_buf.data())+boost::asio::buffer_size(_buf.data());
如果(!boost::以(r,行结束标记)结束)
返回0;
返回1;

我不知道你的问题的答案,但我可以用VS2008重新编译你的崩溃,但不能用VS2010。你编译过Boost ASIO吗?我认为这是少数需要编译的东西之一。虽然它是一个只包含头的库,但它依赖于Boost::system,而Boost::system需要单独编译。你做过所有像删除所有c这样的“蠢事”吗Compiled items and re build?你确定你的boost版本使用了与你的应用程序版本相同的编译器选项吗?在VS2005中,使用boost 1.50,此main在发行版中返回0,在调试版中返回1。我不确定我是否遵循了-the
std::copy()
对输出迭代器的操作发生在
std::cout
上。
asio::streambuf
os
相关,而不是
cout
。写入
cout
不应该影响
os
。你当然是对的;我误读了这一点。我感到困惑,必须对此进行进一步的考虑。不会吧至少不是asio streambuf中的第一个错误。也得出了同样的结论。多缓冲区支持有时会有点混乱。@Shane Powell我不同意。从asio的文档中,buffers\u begin将迭代器返回到数据而不是缓冲区序列。buffers\u迭代器类模板允许缓冲区序列(即满足MutableBufferSequence或ConstBufferSequence要求的类型)将被遍历,就像它们是连续的字节序列一样。