3

In gcc I measured sizeof(std::stack<int>) and it show 80 bytes. Why it is so large?

It can contain pointer to the top and the size. Even if it contain also the pointer to the allocator, it should be not more than 20 bytes.

Another example, sizeof(std::set<int>) is 48 bytes.

  • Yes that does seem a bit fat (on a cursory glance), for both containers. Yes you are correct about the size pretty much having to be a member - as asking for the size needs to be O(1) from C++11. What does your implementation have as data members? – Bathsheba Oct 28 '21 at 07:56
  • 4
    `stack` is only containter adapter. By default, `std::deque` is stored inside adapter. It is rather hard to implement deque by pointer and the size variable. – rafix07 Oct 28 '21 at 07:58
  • By default (it is possible to change) a `std::stack` contains a `std::deque` which has elements that are not contiguous, requirements on complexity of some operations, etc etc. That set of properties requires a number of elements of book-keeping (e.g. at least a pair of iterators, storing the size separately, etc) that will be represented in the size of a `std::deque`. – Peter Oct 28 '21 at 08:03

1 Answers1

8

You know you can read the source yourself, right?

class stack has a single member, a _Sequence which is a type alias for std::deque<_Tp> (and _Tp is int).

Off to the implementation of std::deque: that is just a wrapper around _Deque_base, which is a wrapper around _Deque_impl. That in turn holds a _Deque_impl_data, and finally we arrive at the following:

struct _Deque_impl_data {
    _Map_pointer _M_map;
    size_t _M_map_size;
    iterator _M_start;
    iterator _M_finish;
...
};

where iterator is a _Deque_iterator with the following members:

struct _Deque_iterator {
...
      _Elt_pointer _M_cur;
      _Elt_pointer _M_first;
      _Elt_pointer _M_last;
      _Map_pointer _M_node;
...
}

Summing it all up: each iterator holds 4 pointers (=32 bytes in a 64-bit system), and then _Deque_impl_data holds another two pointers, for a total of 80 bytes.

Evg
  • 25,259
  • 5
  • 41
  • 83
Botje
  • 26,269
  • 3
  • 31
  • 41
  • But why is this implemented using std::deque (double-ended queue)? It doesn't need such functionality. It does not contain an iterator, it can be inserted or removed only from the top. – Victor Telnov Oct 28 '21 at 13:30
  • There's an [SO question](https://stackoverflow.com/questions/102459/why-does-stdstack-use-stddeque-by-default) about that – Botje Oct 28 '21 at 18:40
  • No, that doesn't answer my question. My question is, why does it use a double-ended queue, but not a one-ended queue/list/or something like that and without any iterator item? It's excessive and now it weights 80 bytes. The implementation of such plain stack is very simple. From the very weighted standard stack, I need include additional non-standard library. – Victor Telnov Oct 28 '21 at 23:26