c++11 - Constant container (map) - eliminate heap allocation -


if create static const std::map, allocate memory on heap. following code throws bad_alloc:

#include <iostream> #include <map>  class { public:     static const std::map<int, int> a; };  const std::map<int, int> a::a = { { 1, 3} , { 2, 5} };  void* operator new  ( std::size_t count ) {     throw std::bad_alloc(); }  int main (void) {     for(auto &ai: a::a) {         std::cout << ai.first << " " << ai.second << "\n";     }     return 0; } 

is possible create constant map somehow without having memory allocation?

as igor tandetnik suggested, custom allocator trick. following quick'n'dirty example of simple linear allocator, returns memory slots static buffer:

#include <iostream> #include <map> #include <cassert>  template <typename t> class linearallocator {     static constexpr size_t _maxalloc = 1<<20;     using buffer = std::array<t, _maxalloc>;     using freelist = std::array<bool, _maxalloc>;      static buffer _buffer;     static freelist _allocated; public:     typedef t* pointer;     typedef t value_type;      template<typename u>     struct rebind { typedef linearallocator<u> other; };      pointer allocate(size_t /*n*/, const void *hint=0) {         for(size_t = 0; < _maxalloc; ++i) {             if(!_allocated[i]) {                 _allocated[i] = true;                 return &_buffer[i];             }         }         throw std::bad_alloc();     }      void deallocate(pointer p, size_t /*n*/) {         assert(p >= &_buffer[0] && p < &_buffer[_maxalloc]);         _allocated[p-&_buffer[0]] = false;     }      linearallocator() throw() { }     linearallocator(const linearallocator &a) throw() { }     template <class u>                         linearallocator(const linearallocator<u> &a) throw() { }     ~linearallocator() throw() { } };  template <typename t> typename linearallocator<t>::buffer linearallocator<t>::_buffer;  template <typename t> typename linearallocator<t>::freelist linearallocator<t>::_allocated;  using mymap = std::map<int, int, std::less<int>,                        linearallocator<std::pair<int,int> > >;  // make sure notice if new gets called void* operator new(size_t size) {     std::cout << "new called" << std::endl;  }  int main() {     mymap m;     m[0] = 1; m[1] = 3; m[2] = 8;      for(auto & p : m)         std::cout << p.first << ": " << p.second << std::endl;      return 0; } 

output:

0: 1 1: 3 2: 8 

note allocator handle requests single slots @ time. i'm sure figure out how extend according requirements.


Comments

Popular posts from this blog

javascript - oscilloscope of speaker input stops rendering after a few seconds -

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -