这个程序(它已从较大的程序缩小)在Windows 7下以vs2008 Release(Win32)模式编译后总是崩溃。我不熟悉汇编代码并且不知道它' sa编译器或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;
}
答案 0 :(得分:1)
编辑:我误解了代码,抱歉。
您的游标和结束迭代器指向无效内存。您修改了在复制期间重新分配到输出迭代器的基础streambuf。 asio streambuf允许你出于性能原因访问原始内存,但需要注意的是你必须担心这样的事情。
调试和释放将改变分配和释放行为与分配块的基础大小以及如何对内存进行隔离,保护,初始化,对齐等方式的行为。
在复制操作后构造迭代器以修复问题。
答案 1 :(得分: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;