"map/set iterators incompatible"映射销毁,取决于构造函数调用

"map/set iterators incompatible" on map destruction, dependent on constructor call

本文关键字:取决于 函数调用 映射 map set iterators incompatible      更新时间:2023-10-16

我正在构建测试,在Visual Studio 2013中遇到了此调试断言问题,2013年11月编译器,调试构建,32位:
"表达式:映射/设置迭代器不兼容"
"标准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>>::运算符==(const std::_Tree_const_idterator>>>>&_Right)第328行C++tremppi_test.exe!std::_Tree>,std::less,std::分配器>>,0>>::擦除++tremppi_test.exe!std::_Tree>,std::less,std::分配器>>,0>>::_Tidy()行2230 C++tremppi_test.exe!std::_Tree>,std::less,std::分配器>>,0>>:~树>,std::less,std::分配器>>>,0>>()第1193 C行++tremppi_test.exe!std::map>,std::less,std::分配器>>:~ map>,std::less,std::分配器>>()C++tremppi_test.exe!动力学::参数::~参数()C++tremppi_test.exe!动力学::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::标量删除析构函数'(unsigned int)C++tremppi_test.exe!std::分配器::销毁(动力学::组件*_Ptr)行608 C++tremppi_test.exe!std::allocator_traits>::destroy(std::分配器&_Al,动力学::组件*_Ptr)第731行C++tremppi_test.exe!std::_Wrap_alloc>::破坏(动力学::组分*_Ptr)第879行C++tremppi_test.exe!std::_Destory_range>>(动力学::第一组分,动力学::最后一组分,std::_Wrap_alloc>&_Al,std::_Nonscalar_prt_iterator_tag__formal)第82行C++tremppi_test.exe!std::_Destory_range>>(动力学::第一组分,动力学::最后组分,std::_Wrap_alloc>&_Al)第96行C++tremppi_test.exe!std::vector>::_Destroy(动力学::组分*First,动力学::成分*Last)线1567 C++tremppi_test.exe!std::vector>::_Tidy()行1628 C++tremppi_test.exe!std::vector>::~vector>()线路946C++tremppi_test.exe!动力学::~动力学()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加载符号]

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