При наличии вопроса памяти о СТЛИ контейнеры ... помните, что вся память, которую они получают, поступает от распределителя , который вы передаете (который по умолчанию равен std::allocator
).
Таким образом, простое регулирование распределителя должно отвечать большинству вопросов. Жить демо на liveworkspace, выход представлен здесь std::list<int, MyAllocator>
:
allocation of 1 elements of 24 bytes each at 0x1bfe0c0
deallocation of 1 elements of 24 bytes each at 0x1bfe0c0
Таким образом, 24 байт в этом случае, который на платформе 64 бита и следовало ожидать: два указателя на следующий и предыдущий, 4 байтов и 4 байта заполнения.
Полный код перечисление:
#include <iostream>
#include <limits>
#include <list>
#include <memory>
template <typename T>
struct MyAllocator {
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef T const* const_pointer;
typedef T const& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template <typename U>
struct rebind {
typedef MyAllocator<U> other;
};
MyAllocator() = default;
MyAllocator(MyAllocator&&) = default;
MyAllocator(MyAllocator const&) = default;
MyAllocator& operator=(MyAllocator&&) = default;
MyAllocator& operator=(MyAllocator const&) = default;
template <typename U>
MyAllocator(MyAllocator<U> const&) {}
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
pointer allocate(size_type n, void const* = 0) {
pointer p = reinterpret_cast<pointer>(malloc(n * sizeof(value_type)));
std::cout << "allocation of " << n << " elements of " << sizeof(value_type) << " bytes each at " << (void const*)p << "\n";
return p;
}
void deallocate(pointer p, size_type n) {
std::cout << "deallocation of " <<n << " elements of " << sizeof(value_type) << " bytes each at " << (void const*)p << "\n";
free(p);
}
size_type max_size() const throw() { return std::numeric_limits<size_type>::max()/sizeof(value_type); }
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(); }
};
template <typename T>
using MyList = std::list<T, MyAllocator<T>>;
int main() {
MyList<int> l;
l.push_back(1);
}
Спекуляция: Возможно, некоторые байты выравнивание (дополнение). –
Проверьте источник или запустите его в своем отладчике и распечатайте его. – jthill
Еще один способ: использовать обработчик памяти для отслеживания памяти, используемой вашей программой. Затем создайте новый 'list'. Сохраните выделенную память. Добавить «T» в список. Дельта в используемой памяти будет равна 'sizeof (list_node) + sizeof (T)', поэтому вычитаем 'sizeof (T)' из дельта, чтобы получить 'sizeof (list_node)'. –
Wug