5

std::list はその実装でリンクされたリストを使用しますが、リスト内の各要素の大きさ (ペイロードを除く) はどれくらいですか?

テストでは、Windows 7 マシンで mingw (mingw-64 ではない) を使用して、各要素が int の各要素に対して 24 バイトを使用します。

ただし、左へのポインターと右へのポインターは、4 + 4 = 8 バイトしかありません。int はわずか 4 バイト (sizeof(void*) と sizeof(int) で決定) なので、気になるのですが、余分なスペースはどこにあるのでしょうか?

(テストには、多くの要素を作成し、プログラムのサイズを確認し、さらに多くの要素を作成し、プログラムのサイズを再度確認し、差をとることが含まれていました)

4

1 に答える 1

8

STL コンテナーに関するメモリの質問がある場合...それらが取得するすべてのメモリは、渡したアロケータ(デフォルトは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 ビット プラットフォームでは予想されます。次と前の 2 つのポインタ、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);
}
于 2013-04-11T06:38:02.720 に答える