2013-04-11 3 views
4

std :: list использует связанные списки в своей реализации, насколько велики каждый из элементов в списке (минус полезная нагрузка)?Каков размер каждого элемента в std :: list?

При тестировании с использованием mingw (не mingw-64) на машине Windows 7 каждый элемент занимает 24 байта для каждого элемента int.

Указатель слева и указатель справа всего 4 + 4 = 8 байтов! и int составляет всего 4 байта (как определено sizeof (void *) и sizeof (int)), так что мне любопытно, будет ли лишнее пространство?

(тест включал сделать много элементов, видя размер программы, делая больше элементов и снова увидеть размер программы, принимая разницу)

+1

Спекуляция: Возможно, некоторые байты выравнивание (дополнение). –

+2

Проверьте источник или запустите его в своем отладчике и распечатайте его. – jthill

+0

Еще один способ: использовать обработчик памяти для отслеживания памяти, используемой вашей программой. Затем создайте новый 'list '. Сохраните выделенную память. Добавить «T» в список. Дельта в используемой памяти будет равна 'sizeof (list_node) + sizeof (T)', поэтому вычитаем 'sizeof (T)' из дельта, чтобы получить 'sizeof (list_node)'. – Wug

ответ

8

При наличии вопроса памяти о СТЛИ контейнеры ... помните, что вся память, которую они получают, поступает от распределителя , который вы передаете (который по умолчанию равен 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); 
} 
Смежные вопросы