-1

For the following struct, since v is a dynamically allocated object, how would the memory alignment work? Is the size of struct S constant, even as the size of v goes? So does v essentially work as a pointer (or some kind of wrapper of a pointer)?

struct S {
    ANY_TYPE a;
    std::vector<ANY_TYPE> v;
} s;

If the answer is yes to all the above questions, then as the size of v goes, where is the memory of its members stored? Are these considered memory on heap or on stack?

Edit: I see downvotes for this question and realized I should've done more research into std::vector itself. I read this post, which made everything clear. Thanks for the answers tho!

tpoker
  • 492
  • 1
  • 5
  • 15
  • 1
    Possible duplicate of [When vectors are allocated, do they use memory on the heap or the stack?](https://stackoverflow.com/questions/8036474/when-vectors-are-allocated-do-they-use-memory-on-the-heap-or-the-stack) – 1201ProgramAlarm Sep 19 '18 at 04:07

2 Answers2

6

v is not dynamically allocated. The std::vector itself is part of the S object. v does, however, own a dynamically allocated buffer.

What this means is that sizeof(S) is constant. It will always be sizeof(ANY_TYPE) + sizeof(std::vector<ANY_TYPE>) + padding.

Essentially, S will be laid out in memory something like this (possibly with some padding between a and v to maintain alignment):

  S
+---+
|   |
| a |
|   |
+---+
|   |
| v |    dynamically allocated buffer
|   |  +------+------+-----+
| +----> v[0] | v[1] | ... |
|   |  +------+------+-----+
+---+
Miles Budnek
  • 28,216
  • 2
  • 35
  • 52
  • Thanks for the concise and helpful answer! So can I understand the source of the left arrow in your drawing as a pointer wrapped in the object v? – tpoker Sep 19 '18 at 02:04
  • 1
    Yes, `std::vector` generally contains a pointer to the first element of its dynamically allocated buffer. (It usually has two other members: its current size and capacity). – Miles Budnek Sep 19 '18 at 02:07
0

v is definitely a wrapper of at least a pointer and (depending on the implementation) some other accounting. The on-stack (or in-array) footprint of v will be limited to only those members declared directly within the std::vector class, and yes, that means that the size of v, and therefore the size of instances of S, will be constant.

The number of bytes consumed on behalf of v (and instances of S) will depend on how much heap memory is allocated by v in the course of its construction and lifetime.

What memory is used for the immediate members of S (including v) is determined by the code doing the declaration:

void my_func() {
    S s1;          // `s1` and its members `a` and `v` are all on the stack
                   //  ...though `v` will allocate heap memory for its own use
    S* s2 = new S; // `s2` points to a heap-allocated instance of `S` 
Derek T. Jones
  • 1,800
  • 10
  • 18