C++ boost::spirit::保留所有内存损坏

C++ boost::spirit::保留所有内存损坏,c++,boost,boost-spirit,memory-corruption,boost-any,C++,Boost,Boost Spirit,Memory Corruption,Boost Any,我有一个很大的代码库,可以使用或(取决于宏定义) hold_any似乎与boost::any(例如or)和更快()兼容,但我在使用hold_any(boost v1.55/1.54/1.53)时遇到了几个分段错误 这是一个最小的工作示例,显示了与原始代码相同的问题: #include <iostream> #include <string> #include <vector> #include <boost/spirit/home/support/de

我有一个很大的代码库,可以使用或(取决于宏定义)

hold_any
似乎与
boost::any
(例如or)和更快()兼容,但我在使用
hold_any
(boost v1.55/1.54/1.53)时遇到了几个分段错误

这是一个最小的工作示例,显示了与原始代码相同的问题:

#include <iostream>
#include <string>
#include <vector>

#include <boost/spirit/home/support/detail/hold_any.hpp>

typedef boost::spirit::hold_any any;
typedef std::vector<any> vany;

int main()
{
  vany data0, data1;

  for (unsigned i(0); i < 1000; ++i)
  {
    std::string s("test_test_test");
    data0.push_back(any(s));
  }

  const unsigned n(data0.size());
  vany::iterator iter(data0.begin());

  for (unsigned i(0); i < n; ++i)
  {
    std::cout << "Moving " << i << std::endl;

    data1.push_back(*iter);
    iter = data0.erase(iter);
  }

  return 0;
}
#包括
#包括
#包括
#包括
typedef boost::spirit::hold_any;
typedef标准::向量向量向量;
int main()
{
vany data0,data1;
for(无符号i(0);i<1000;+i)
{
std::字符串s(“test_test_test”);
数据0.推回(任何);
}
常量无符号n(data0.size());
迭代器iter(data0.begin());
for(无符号i(0);istd::cout你应该不要使用
hold_any
,因为它在
detail/hold_any.hpp中是有原因的

这就是说,
hold\u any
的拷贝分配似乎被破坏了。我已经用一个建议的修复程序创建了

在没有修复的情况下,以下程序演示UB(因为编译器生成浅赋值运算符,这是首选):

#包括
#包括
#包括
typedef boost::spirit::hold_any;
int main()
{
任何b;
{
任何a;
a=std::string(“test_test_test”);
b=a;
}

std::我不能谢谢你,我不知道。很遗憾,
hold\u any
不是一个现成的
boost:any
替代品:SBO在我的程序中是一个很大的增益。你知道其他区别吗?如果这是“唯一的”更新以获得适当的c++11支持同时,我发现了这张旧票:。在我看来,非模板分配构造函数也应该添加到您的补丁中。@manlio其实没关系,只要我们始终为副本分配提供“最佳”重载(参见示例)
#include <iostream>
#include <string>

#include <boost/spirit/home/support/detail/hold_any.hpp>

typedef boost::spirit::hold_any any;

int main()
{
    any b;
    {
        any a;
        a = std::string("test_test_test");
        b = a;
    }

    std::cout << "b: " << b << '\n';
}
==11827== Invalid read of size 8
==11827==    at 0x5E9D793: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std
==11827==    by 0x4012FC: boost::spirit::detail::fxns<mpl_::bool_<true> >::type<std::string, char>::stream_out(std::ostream&, void* const*) (hold_any.hpp:113)
==11827==    by 0x4010F5: std::basic_ostream<char, std::char_traits<char> >& boost::spirit::operator<< <char>(std::basic_ostream<char, std::char_traits<char> >&, boost::spirit::basic_hold_any<char> const&) (hold_any.hpp:368)
==11827==    by 0x400FC9: main (test.cpp:17)
==11827==  Address 0x8ac1650 is 0 bytes inside a block of size 39 free'd
==11827==    at 0x4C2BADC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11827==    by 0x5EC405E: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==11827==    by 0x401204: boost::spirit::detail::fxns<mpl_::bool_<true> >::type<std::string, char>::static_delete(void**) (hold_any.hpp:89)
==11827==    by 0x401328: boost::spirit::basic_hold_any<char>::~basic_hold_any() (hold_any.hpp:246)
==11827==    by 0x4010B4: boost::spirit::basic_hold_any<char>::~basic_hold_any() (hold_any.hpp:245)
==11827==    by 0x400FA0: main (test.cpp:15)