Thanks for the link, looks interesting

.

I have to note though, that the memory usage of most STL containers can't be too surprising.

List is a doubly linked list, so each node will contain two 8 byte pointers (on 64-bit) as well as the value. Set is probably a binary search tree, so it will need at least left and right pointers. unordered_set might be a hash-table of some sort, which will need to not be full in order to be efficient.

If you change his custom allocator's constructor to print some information:

MemoryCountingAllocator() : base() {

std::cout << "+ Allocator for " << __PRETTY_FUNCTION__

<< ", with size " << sizeof(T) << std::endl;

}

You get something like:

Displaying memory usage in bytes.

Filling data structures with 1024 elements and reporting the per element memory usage.

+ Allocator for MemoryCountingAllocator<unsigned int>::MemoryCountingAllocator() [T = unsigned int], with size 4

memory usage per element of a vector<uint32_t> : 4

+ Allocator for MemoryCountingAllocator<std::_List_node<unsigned int> >::MemoryCountingAllocator() [T = std::_List_node<unsigned int>], with size 24

memory usage per element of a list<uint32_t> : 24

+ Allocator for MemoryCountingAllocator<unsigned int>::MemoryCountingAllocator() [T = unsigned int], with size 4

memory usage per element of a deque<uint32_t> : 4.64062

+ Allocator for MemoryCountingAllocator<std::__detail::_Hash_node<unsigned int, false> >::MemoryCountingAllocator() [T = std::__detail::_Hash_node<unsigned int, false>], with size 16

memory usage per element of an unordered_set<uint32_t> : 29.6016

+ Allocator for MemoryCountingAllocator<std::_Rb_tree_node<unsigned int> >::MemoryCountingAllocator() [T = std::_Rb_tree_node<unsigned int>], with size 40

memory usage per element of a set<uint32_t> : 40

Which shows that list, set, and unordered_set are allocating nodes for their respective implementations and not just uint32_t.