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
Post a Comment