1

I am building tests and I got this debug assertion trouble in Visual Studio 2013, November 2013 compiler, Debug build, 32bit:
"Expression: map/set iterators incompatible"
"Standard C++ Libraries Invalid Argument" && 0

The error occurs when leaving the function scope where the destructor of the local object is called.

The weird thing is that I can fix it by changing the code syntax to what I think should be equivalent. More precisely this is the broken code:

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 } 
});

while this is working note that I only moved the map constructor call out of the Param constructor call

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 } 
});

In my mind the above two should be equivalent - each time I use the initializer list which gets rvalue references (either from temporary or from move) and stores them within, so I dunno why the error, the type of error also baffles me.

For completeness, I also add the definition of the Kinetics object:

#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. 
};

And lastly the call stack:

tremppi_test.exe!std::_Tree_const_iterator > > > > >::operator==(const std::_Tree_const_iterator > > > > > & _Right) Line 328 C++ tremppi_test.exe!std::_Tree >,std::less,std::allocator > > >,0> >::erase(std::_Tree_const_iterator > > > > > _First, std::_Tree_const_iterator > > > > > _Last) Line 1512 C++ tremppi_test.exe!std::_Tree >,std::less,std::allocator > > >,0> >::_Tidy() Line 2230 C++ tremppi_test.exe!std::_Tree >,std::less,std::allocator > > >,0> >::~_Tree >,std::less,std::allocator > > >,0> >() Line 1193 C++ tremppi_test.exe!std::map >,std::less,std::allocator > > > >::~map >,std::less,std::allocator > > > >() 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::scalar deleting destructor'(unsigned int) C++ tremppi_test.exe!std::allocator::destroy(Kinetics::Component * _Ptr) Line 608 C++ tremppi_test.exe!std::allocator_traits >::destroy(std::allocator & _Al, Kinetics::Component * _Ptr) Line 731 C++ tremppi_test.exe!std::_Wrap_alloc >::destroy(Kinetics::Component * _Ptr) Line 879 C++ tremppi_test.exe!std::_Destroy_range > >(Kinetics::Component * _First, Kinetics::Component * _Last, std::_Wrap_alloc > & _Al, std::_Nonscalar_ptr_iterator_tag __formal) Line 82 C++ tremppi_test.exe!std::_Destroy_range > >(Kinetics::Component * _First, Kinetics::Component * _Last, std::_Wrap_alloc > & _Al) Line 96 C++ tremppi_test.exe!std::vector >::_Destroy(Kinetics::Component * _First, Kinetics::Component * _Last) Line 1567 C++ tremppi_test.exe!std::vector >::_Tidy() Line 1628 C++ tremppi_test.exe!std::vector >::~vector >() Line 946 C++ tremppi_test.exe!Kinetics::~Kinetics() C++ tremppi_test.exe!tremppi_validate(int argc, char * * argv) Line 153 C++ tremppi_test.exe!basic_validate_test() Line 19 C++ tremppi_test.exe!CoreTest_AllPrograms_Test::TestBody() Line 13 C++ [External Code] tremppi_test.exe!RUN_ALL_TESTS() Line 2289 C++ tremppi_test.exe!tremppi_test(int argc, char * * argv) Line 19 C++ tremppi_test.exe!main(int argc, char * * argv) Line 8 C++ [External Code] [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Adam Streck
  • 340
  • 2
  • 15
  • Are you sure you're using VS2013, and not the VS14 CTP? VS2013 does not allow you to `=default` the move constructor or assignment operator. If I try using your `NO_COPY` macro on VS2013 Update 3, I get this error (as expected) `error C2610: '...' : is not a special member function which can be defaulted` – Praetorian Aug 27 '14 at 16:22
  • That will be most likely because you are not using the compiler I listed above. You can check the features of the particular compiler version here: http://blogs.msdn.com/b/vcblog/archive/2013/11/18/announcing-the-visual-c-compiler-november-2013-ctp.aspx – Adam Streck Aug 27 '14 at 17:18
  • 1
    You might be hitting [this bug](http://stackoverflow.com/questions/20165166/double-delete-in-initializer-list-vs-2013) – Igor Tandetnik Aug 27 '14 at 22:03
  • @IgorTandetnik thanks, it seems most likely like the issue. On the related feedback page it lists that: "The fix should show up in the future release of Visual C++. Xiang Fan Visual C++ Team" Maybe someone has VS14 to try it out? – Adam Streck Aug 28 '14 at 09:10

1 Answers1

0

This is (most likely) listed as a closed bug #807419 https://connect.microsoft.com/VisualStudio/feedback/details/807419/initializer-lists-leaking-memory and is probably related only to the compiler version in question. Using updated VS13 (that won't compile the code above) or VS14 should probably prevent such a problem.

Adam Streck
  • 340
  • 2
  • 15