c++ - std::bad_alloc when inserting into std::unordered_map? -


i'm getting std::bad_alloc following code:

typedef std::unordered_map<chash, block_extended_info> map_type; map_type m_foo;   // transgressor: auto r = m_foo.insert(map_type::value_type(id, bei)); 

it happens of time while running test cases use method containing line, , other times doesn't. had changed code use m_foo[id] = bei, caused stop happening 1 compilation, when recompiled again failed, changed above, continued fail. issue deeper that.

i sure it's not matter of running out of memory since have top running while test cases running , doesn't anywhere near filling memory.

what may causing std::bad_alloc? in details of chash , block_extended_info may causing this? objects of types copied , passed around on place in other parts of code , doesn't cause issues.

here's definition of chash:

class chash {   char data[32]; }; 

and following required define block_extended_info:

class csignature {   chash c, r; }; enum foob { /* ... */ }; class ct {   uint64_t a, b;   foob c; }; typedef boost::variant< /* structs ints, maps, vectors of ints */ > txin_v; typedef boost::variant< /* similar structs */ > txout_target_v; struct tx_out {     uint64_t a;     txout_target_v b; }; class transaction_prefix { public:   size_t   version;   uint64_t unlock_time;   std::vector<uint8_t> extra;  protected:   std::vector<txin_v> a;   std::vector<tx_out> b;   std::vector<ct> c;   std::vector<ct> d; }; class transaction: public transaction_prefix { public:   std::vector<std::vector<csignature> > signatures; }; struct block_header {   uint8_t  major_version;   uint8_t  minor_version;   uint64_t timestamp;   chash    prev_id;   uint32_t nonce; }; struct block: public block_header {   transaction miner_tx;   std::vector<chash> tx_hashes;   uint16_t food_id;   csignature food_sig; }; struct block_extended_info {   block    bl;   uint64_t height;   size_t   block_cumulative_size;   uint64_t cumulative_difficulty;   uint64_t already_generated_coins; }; 

stepping around relevant area in gdb, here latest few lines lead bad_alloc:

cryptonote::transaction::transaction(cryptonote::transaction const&) () @ /usr/include/c++/4.8/bits/stl_vector.h:313 313       { this->_m_impl._m_finish = 646       { return size_type(this->_m_impl._m_finish - this->_m_impl._m_start); } 91      : _tp_alloc_type(__a), _m_start(0), _m_finish(0), _m_end_of_storage(0) 168       { return __n != 0 ? _m_impl.allocate(__n) : 0; } 183     this->_m_impl._m_end_of_storage = this->_m_impl._m_start + __n; 181     this->_m_impl._m_start = this->_m_allocate(__n); 182     this->_m_impl._m_finish = this->_m_impl._m_start; 183     this->_m_impl._m_end_of_storage = this->_m_impl._m_start + __n; 310       vector(const vector& __x) 117     __uninit_copy(__first, __last, __result); cryptonote::tx_out* std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<cryptonote::tx_out const*, std::vector<cryptonote::tx_out, std::allocator<cryptonote::tx_out> > >, cryptonote::tx_out*>(__gnu_cxx::__normal_iterator<cryptonote::tx_out const*, std::vector<cryptonote::tx_out, std::allocator<cryptonote::tx_out> > >, __gnu_cxx::__normal_iterator<cryptonote::tx_out const*, std::vector<cryptonote::tx_out, std::allocator<cryptonote::tx_out> > >, cryptonote::tx_out*) ()     @ /usr/include/c++/4.8/bits/stl_uninitialized.h:68 68          __uninit_copy(_inputiterator __first, _inputiterator __last, 74            (; __first != __last; ++__first, ++__cur) 83      } cryptonote::transaction::transaction(cryptonote::transaction const&) () @ /usr/include/c++/4.8/bits/stl_vector.h:313 313       { this->_m_impl._m_finish = 646       { return size_type(this->_m_impl._m_finish - this->_m_impl._m_start); } 91      : _tp_alloc_type(__a), _m_start(0), _m_finish(0), _m_end_of_storage(0) 646       { return size_type(this->_m_impl._m_finish - this->_m_impl._m_start); } 168       { return __n != 0 ? _m_impl.allocate(__n) : 0; } 101     if (__n > this->max_size()) 104     return static_cast<_tp*>(::operator new(__n * sizeof(_tp))); 183     this->_m_impl._m_end_of_storage = this->_m_impl._m_start + __n; 181     this->_m_impl._m_start = this->_m_allocate(__n); 182     this->_m_impl._m_finish = this->_m_impl._m_start; 183     this->_m_impl._m_end_of_storage = this->_m_impl._m_start + __n; 310       vector(const vector& __x) 74            (; __first != __last; ++__first, ++__cur) 71        _forwarditerator __cur = __result; 75      { ::new(static_cast<void*>(__p)) _t1(std::forward<_args>(__args)...); } 748     ++_m_current; 74            (; __first != __last; ++__first, ++__cur) 313       { this->_m_impl._m_finish = 646       { return size_type(this->_m_impl._m_finish - this->_m_impl._m_start); } 91      : _tp_alloc_type(__a), _m_start(0), _m_finish(0), _m_end_of_storage(0) 646       { return size_type(this->_m_impl._m_finish - this->_m_impl._m_start); } 168       { return __n != 0 ? _m_impl.allocate(__n) : 0; } 183     this->_m_impl._m_end_of_storage = this->_m_impl._m_start + __n; 181     this->_m_impl._m_start = this->_m_allocate(__n); 182     this->_m_impl._m_finish = this->_m_impl._m_start; 183     this->_m_impl._m_end_of_storage = this->_m_impl._m_start + __n; 310       vector(const vector& __x) 74            (; __first != __last; ++__first, ++__cur) 570   class transaction: public transaction_prefix 313       { this->_m_impl._m_finish = 646       { return size_type(this->_m_impl._m_finish - this->_m_impl._m_start); } 91      : _tp_alloc_type(__a), _m_start(0), _m_finish(0), _m_end_of_storage(0) 646       { return size_type(this->_m_impl._m_finish - this->_m_impl._m_start); } 168       { return __n != 0 ? _m_impl.allocate(__n) : 0; } 101     if (__n > this->max_size()) 104     return static_cast<_tp*>(::operator new(__n * sizeof(_tp))); 181     this->_m_impl._m_start = this->_m_allocate(__n); 183     this->_m_impl._m_end_of_storage = this->_m_impl._m_start + __n; 181     this->_m_impl._m_start = this->_m_allocate(__n); 182     this->_m_impl._m_finish = this->_m_impl._m_start; 183     this->_m_impl._m_end_of_storage = this->_m_impl._m_start + __n; 310       vector(const vector& __x) 74            (; __first != __last; ++__first, ++__cur) 101     if (__n > this->max_size()) 75      { ::new(static_cast<void*>(__p)) _t1(std::forward<_args>(__args)...); } 646       { return size_type(this->_m_impl._m_finish - this->_m_impl._m_start); } 91      : _tp_alloc_type(__a), _m_start(0), _m_finish(0), _m_end_of_storage(0) 168       { return __n != 0 ? _m_impl.allocate(__n) : 0; } 101     if (__n > this->max_size()) 102       std::__throw_bad_alloc(); 

as πάντα ῥεῖ suspected, problem elsewhere.

the code listed in function called add_block_as_invalid(...). call site looked this:

// parameter, iterators m_alternative_chains std::list<blocks_ext_by_hash::iterator>& alt_chain;   for(auto alt_ch_iter = alt_chain.begin();      alt_ch_iter != alt_chain.end();      alt_ch_iter++)  {     // ....     auto ch_ent = *alt_ch_iter;     // ....     m_alternative_chains.erase(ch_ent);      for(auto alt_ch_to_orph_iter = ++alt_ch_iter;          alt_ch_to_orph_iter != alt_chain.end();          alt_ch_to_orph_iter++)      {         add_block_as_invalid((*alt_ch_iter)->second, (*alt_ch_iter)->first);         m_alternative_chains.erase(*alt_ch_to_orph_iter);     } } 

the call add_block_as_invalid kept dereferencing alt_ch_iter, had been erased.


Comments

Popular posts from this blog

node.js - Mongoose: Cast to ObjectId failed for value on newly created object after setting the value -

gradle error "Cannot convert the provided notation to a File or URI" -

python - NameError: name 'subprocess' is not defined -