" map / set迭代器不兼容"在地图上销毁,依赖于构造函数调用

时间:2014-08-27 11:48:22

标签: c++ c++11 map stl visual-studio-2013

我正在构建测试,我在Visual Studio 2013中遇到了这个调试断言问题,2013年11月编译器,Debug build,32bit:
"表达式:map / set迭代器不兼容"
"标准C ++库无效参数" &安培;&安培; 0

当函数作用域调用本地对象的析构函数时会发生错误。

奇怪的是我可以通过将代码语法更改为我认为应该相同的语法来修复它。更确切地说,这是破碎的代码:

Kinetics kinetics;
kinetics.components.emplace_back(Kinetics::Component{ 0, Kinetics::Params{}, 1, 1 });
kinetics.components[0].params.push_back(Kinetics::Param{
    "",
    vector<size_t>{ 0, 1 },
    map < size_t, vector<size_t> >{{0, vector<size_t>{ 0 }}},
    vector<size_t>{ 1 } 
});
kinetics.components[0].params.push_back(Kinetics::Param{
    "",
    vector<size_t>{ 0, 1 },
    map < size_t, vector<size_t> >{{0, vector<size_t>{ 1 }}},
    vector<size_t>{ 0 } 
});

虽然这有效请注意我只是将地图构造函数调用移出Param构造函数调用

Kinetics kinetics;
kinetics.components.emplace_back(Kinetics::Component{ 0, Kinetics::Params{}, 1, 1 });
map < size_t, vector<size_t> > requirements = map < size_t, vector<size_t> >{{0, vector<size_t>{ 0 }}};
kinetics.components[0].params.push_back(Kinetics::Param{
    "",
    vector<size_t>{ 0, 1 },
    move(requirements),
    vector<size_t>{ 1 } 
});
requirements = map < size_t, vector<size_t> >{{0, vector<size_t>{ 1 }}};
kinetics.components[0].params.push_back(Kinetics::Param{
    "",
    vector<size_t>{ 0, 1 },
    move(requirements),
    vector<size_t>{ 0 } 
});

在我看来,上面两个应该是等价的 - 每次我使用初始化列表获取右值引用(从临时或从移动)并将它们存储在内,所以我不知道为什么错误,错误的类型也困惑我

为了完整性,我还添加了Kinetics对象的定义:

#define NO_COPY(TypeName) \
TypeName() = default;  \
TypeName(TypeName && ) = default;  \
TypeName& operator=(TypeName && ) = default; \
TypeName(const TypeName & ) = delete; \
TypeName& operator=(const TypeName & ) = delete; 

struct Kinetics {
    NO_COPY(Kinetics)

    struct Param {
        string context; ///< String representation of the context.
        vector<size_t> targets; ///< Towards which level this context may regulate.
        map<size_t, vector<size_t>> requirements; ///< vector<size_t> of the source components this param is relevant to, the vector<size_t> are sorted.

        vector<size_t> target_in_subcolor; ///< List of values from different subparametrizations for this specie, share indices between params.
    };
    using Params = vector < Param > ;

    struct Component {
        size_t ID; ///< ID of the component, shared with the model
        Params params; ///< Vector of parameters, sorted lexicographically by the context.
        size_t col_count; ///< Number of subcolors for this specie.
        size_t step_size; ///< In the context of the whole parametrization space, how may changes occur between a subcolor of this specie changes?
    };

    vector<Component> components; ///< Species shared with the model, sorted lexicographically. 
};

最后是调用堆栈:

  

tremppi_test.exe!std :: _ Tree_const_iterator&gt; &GT; &GT; &GT; &gt; :: operator ==(const std :: _ Tree_const_iterator&gt;&gt;&gt;&gt;&gt;&amp; _Right)第328行C ++       tremppi_test.exe!std :: _ Tree&gt ;,std :: less,std :: allocator&gt; &GT; &GT;,0&GT; &gt; :: erase(std :: _ Tree_const_iterator&gt;&gt;&gt;&gt;&gt; _First,std :: _ Tree_const_iterator&gt;&gt;&gt;&gt;&gt; _Last)第1512行C ++       tremppi_test.exe!std :: _ Tree&gt ;,std :: less,std :: allocator&gt; &GT; &GT;,0&GT; &gt; :: _ Tidy()第2230行C ++       tremppi_test.exe!std :: _ Tree&gt ;,std :: less,std :: allocator&gt; &GT; &GT;,0&GT; &gt; ::〜_Tree&gt ;,std :: less,std :: allocator&gt; &GT; &GT;,0&GT; &gt;()第1193行C ++       tremppi_test.exe!std :: map&gt ;,std :: less,std :: allocator&gt; &GT; &GT; &gt; ::〜map&gt ;,std :: less,std :: allocator&gt; &GT; &GT; &gt;()C ++       tremppi_test.exe!Kinetics :: Param :: ~Param()C ++       tremppi_test.exe!Kinetics :: Param :: scalar deleting destructor'(unsigned int) C++ tremppi_test.exe!std::allocator<Kinetics::Param>::destroy<Kinetics::Param>(Kinetics::Param * _Ptr) Line 608 C++ tremppi_test.exe!std::allocator_traits<std::allocator<Kinetics::Param> >::destroy<Kinetics::Param>(std::allocator<Kinetics::Param> & _Al, Kinetics::Param * _Ptr) Line 731 C++ tremppi_test.exe!std::_Wrap_alloc<std::allocator<Kinetics::Param> >::destroy<Kinetics::Param>(Kinetics::Param * _Ptr) Line 879 C++ tremppi_test.exe!std::_Destroy_range<std::_Wrap_alloc<std::allocator<Kinetics::Param> > >(Kinetics::Param * _First, Kinetics::Param * _Last, std::_Wrap_alloc<std::allocator<Kinetics::Param> > & _Al, std::_Nonscalar_ptr_iterator_tag __formal) Line 82 C++ tremppi_test.exe!std::_Destroy_range<std::_Wrap_alloc<std::allocator<Kinetics::Param> > >(Kinetics::Param * _First, Kinetics::Param * _Last, std::_Wrap_alloc<std::allocator<Kinetics::Param> > & _Al) Line 96 C++ tremppi_test.exe!std::vector<Kinetics::Param,std::allocator<Kinetics::Param> >::_Destroy(Kinetics::Param * _First, Kinetics::Param * _Last) Line 1567 C++ tremppi_test.exe!std::vector<Kinetics::Param,std::allocator<Kinetics::Param> >::_Tidy() Line 1628 C++ tremppi_test.exe!std::vector<Kinetics::Param,std::allocator<Kinetics::Param> >::~vector<Kinetics::Param,std::allocator<Kinetics::Param> >() Line 946 C++ tremppi_test.exe!Kinetics::Component::~Component() C++ tremppi_test.exe!Kinetics::Component::标量删除析构函数&#39;(unsigned int)C ++       tremppi_test.exe!std :: allocator :: destroy(Kinetics :: Component * _Ptr)Line 608 C ++       tremppi_test.exe!std :: allocator_traits&gt; :: destroy(std :: allocator&amp; _Al,Kinetics :: Component * _Ptr)731行C ++       tremppi_test.exe!std :: _ Wrap_alloc&gt; :: destroy(Kinetics :: Component * _Ptr)第879行C ++       tremppi_test.exe!std :: _ Destroy_range&gt; &gt;(Kinetics :: Component * _First,Kinetics :: Component * _Last,std :: _ Wrap_alloc&gt;&amp; _Al,std :: _ Nonscalar_ptr_iterator_tag __formal)第82行C ++       tremppi_test.exe!std :: _ Destroy_range&gt; &gt;(Kinetics :: Component * _First,Kinetics :: Component * _Last,std :: _ Wrap_alloc&gt;&amp; _Al)第96行C ++       tremppi_test.exe!std :: vector&gt; :: _ Destroy(Kinetics :: Component * _First,Kinetics :: Component * _Last)Line 1567 C ++       tremppi_test.exe!std :: vector&gt; :: _ Tidy()第1628行C ++       tremppi_test.exe!std :: vector&gt; ::〜vector&gt;()第946行C ++       tremppi_test.exe!Kinetics :: ~Kinetics()C ++       tremppi_test.exe!tremppi_validate(int argc,char * * argv)第153行C ++       tremppi_test.exe!basic_validate_test()第19行C ++       tremppi_test.exe!CoreTest_AllPrograms_Test :: TestBody()第13行C ++       [外部代码]       tremppi_test.exe!RUN_ALL_TESTS()第2289行C ++       tremppi_test.exe!tremppi_test(int argc,char * * argv)第19行C ++       tremppi_test.exe!main(int argc,char * * argv)第8行C ++       [外部代码]       [下面的框架可能不正确和/或缺失,没有为kernel32.dll加载符号]

1 个答案:

答案 0 :(得分:0)

这很可能(很可能)被列为已关闭的错误#807419 https://connect.microsoft.com/VisualStudio/feedback/details/807419/initializer-lists-leaking-memory,并且可能仅与相关的编译器版本有关。使用更新的VS13(不能编译上面的代码)或VS14应该可以防止出现这样的问题。