I am writing a allocator with reference to another instance of some class that keeps track of the number of bytes allocated.
below is a minimal example of what I'm trying to do (adapted from here ), just without a whole memory tracking class, instead I made a reference to some int that collects the bytes that have been allocated so far. This link is assigned inside main and should be passed to CustomAllocator:
#include <limits> // numeric_limits
#include <iostream>
#include <typeinfo> // typeid
#include <vector>
#include <list>
#include <forward_list>
template<typename T>
class CustomAllocator {
public:
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef const T* const_pointer;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template<typename U>
struct rebind {
typedef CustomAllocator<U> other;
};
size_type max_size () const throw() {
return std::numeric_limits<std::size_t>::max() / sizeof(T);
}
CustomAllocator(std::size_t& memAllocated) :
m_totalMemAllocated(memAllocated) {
std::cout << "construct " << typeid(T).name() << std::endl;
}
CustomAllocator(const CustomAllocator& src) :
m_totalMemAllocated(src.m_totalMemAllocated) {
std::cout << "copy construct " << typeid(T).name() << std::endl;
}
template<class U>
CustomAllocator(const CustomAllocator<U>& src) :
m_totalMemAllocated(src.getTotalMemAllocated()) {
}
pointer allocate(size_type num, const void* = 0) {
m_totalMemAllocated += num * sizeof(T);
std::cout << "allocate " << num << " element(s)" << " of size "
<< sizeof(T) << std::endl;
pointer ret = (pointer) (::operator new(num * sizeof(T)));
std::cout << " allocated at: " << (void*) ret << std::endl;
return ret;
}
void deallocate(pointer p, size_type num) {
m_totalMemAllocated -= num * sizeof(T);
std::cout << "deallocate " << num << " element(s)" << " of size "
<< sizeof(T) << " at: " << (void*) p << std::endl;
::operator delete((void*) p);
}
template<typename _U, typename ... _Args>
void construct(_U* p, _Args&&... args) {
::new ((void *) p) _U(std::forward<_Args>(args)...);
}
template<typename _U>
void destroy(_U* p) {
p->~_U();
}
pointer address (reference value) const {
return &value;
}
const_pointer address (const_reference value) const {
return &value;
}
private:
std::size_t& m_totalMemAllocated;
};
template<typename T, typename U>
bool operator==(const CustomAllocator<T> a, const CustomAllocator<U>& b) {
return true;
}
template<typename T, typename U>
bool operator!=(const CustomAllocator<T>& a, const CustomAllocator<U>& b) {
return false;
}
int main() {
std::size_t memAllocated = 0;
CustomAllocator<int> allocatorInstance(memAllocated);
std::vector<int> foo(allocatorInstance);
foo.push_back(23);
foo.push_back(12);
foo.push_back(8);
std::cout << "---" << std::endl;
std::list<double> bar(allocatorInstance);
bar.push_back(3.44);
bar.push_back(1.18);
bar.push_back(2.25);
std::cout << "---" << std::endl;
for (auto x : foo)
std::cout << x << " ";
for (auto x : bar)
std::cout << x << " ";
std::cout << "\nalloc_count: " << memAllocated << std::endl;
std::cout << '\n';
return 0;
}
My problem is that I don’t know how to pass the same state (in the m_totalMemAllocated example) of the dispenser instance to two other containers (here: foo and bar). Since the standard states that C ++ 11 distributors may have a state.
Update:
:)
, CustomAllocators std-; :
std::vector<int, CustomAllocator<int> > foo;
std::list<double, CustomAllocator<double> > bar;
.
, , , ++?
, , , , ( , ).
std::size_t memAllocated = 0;
, , CustomAllocator, memAllocated. , memAllocated2, .
:
, STD-, .
EASTL?