c++ - Bizarre error message in VC12 when attempting to create pool allocator -
c++ - Bizarre error message in VC12 when attempting to create pool allocator -
i attempting create simple pool allocator can work containers list , map. first, have class free_list
inherits node type used container , uses specialized forwards linked list (with memory allocated--allocation occurs when first item allocated allocator) give , take memory requested in allocator's allocate
, deallocate
functions. have class pool_alloc
implements allocator , returns , accepts in allocation , deallocation functions free_list<t>
object types.
the problem kid statement: m_next->give_back(ptr);
under pool_alloc::deallocate
, returns vc12 error c2664: says cannot convert type 'free_list<t>*
' type 'free_list<free_list<t>>*
'.
i not understand why free_list<t>::give_back
expects type free_list<free_list<t>>*
when 1 expect expect free_list<t>*
.
is there way prepare this?
the total source code below:
#include <algorithm> template<class t> class free_list : public t { public: free_list* init(std::size_t num_elements) { m_next = this; free_list* temp = m_next + 1; free_list* runner = m_next; (std::size_t s = 1; s < num_elements; ++s) { runner->m_next = temp; runner = temp; temp = runner + 1; } runner->m_next = nullptr; homecoming m_next; } free_list* obtain() { free_list* head = m_next; m_next = m_next->m_next; homecoming head; } void give_back(free_list* ptr) { ptr->m_next = m_next; m_next = ptr; } free_list* m_next; }; template<class t> class pool_alloc { typedef pool_alloc<t> myt; public: typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef free_list<t> value_type; typedef t& reference; typedef const t& const_reference; typedef free_list<t>* pointer; typedef const free_list<t>* const_pointer; template<class u> struct rebind { typedef pool_alloc<u> other; }; pool_alloc() : data(nullptr), m_next(nullptr), capacity(4096), allocated(0) {} pool_alloc(std::size_t capacity) : data(nullptr), m_next(nullptr), capacity(capacity), allocated(0) {} t* address(reference ref) { homecoming &ref; } const t* address(const_reference ref) const { homecoming &ref; } std::size_t max_size() const { homecoming capacity; } pointer allocate(std::size_t) { if (allocated >= capacity) throw(std::bad_alloc()); if (allocated == 0) { info = (void*) new char[capacity * sizeof(free_list<t>)]; m_next = static_cast<free_list<value_type>*>(data); m_next->init(capacity); } homecoming m_next->obtain(); } void deallocate(pointer ptr, std::size_t) { m_next->give_back(ptr); --allocated; if (allocated == 0) { delete[](char*)(data); info = nullptr; m_next = nullptr; } } template<class t, class... args> void construct(t* ptr, args&&... args) { ::new ((void*) ptr) t(std::forward<args>(args)...); } template <class t> void destroy(t* ptr) { ptr->~t(); } bool operator==(const myt& other) { homecoming (char)(data) == (char)(other.data); } bool operator!=(const myt& other) { homecoming !operator==(other); } private: void* data; free_list<value_type>* m_next; std::size_t capacity; std::size_t allocated; };
it's not weird: you've defined value_type
(incorrectly) free_list<t>
instead of t
, m_next
has type free_list<free_list<t>>
. pointer
, const_pointer
have same issue.
other issues:
pool_alloc
doesn't have proper copy/move/assignment operators defined. pool_alloc
doesn't have templated constructor accepts const pool_alloc<u>&
, won't able initialize pool_alloc::allocate
horrible things if ever tries create std::vector<t, pool_alloc<t>>
. should either assert argument 1 or fallback ::operator new(n * sizeof(t))
if argument greater 1. operator==
, operator!=
should const
. construct
, destroy
const
, or static
. it's not necessary maintain both data
, m_next
, since they're different typed aliases same value - cast m_next
void*
whenever need data
. dumping memory chunk in deallocate
instead of in ~pool_alloc
have pathological performance e.g std::stack<t, std::list<t, pool_alloc<t>>
. the "list" initialization in free_list<t>::init
pointing each node's m_next
pointer @ instead of building list. should be:
void init(std::size_t num_elements) { (std::size_t = 0; < num_elements - 1; ++i) { this[i]->m_next = &this[i + 1]; } this[num_elements - 1]->m_next = nullptr; }
c++ memory-management
Comments
Post a Comment