about address of std::vector<std::vector<int>>

Please frist read the code below:
1
2
3
vector<vector<int>> v({ { 1 }, { 2 } });
v[0].push_back(3);
v[1].push_back(4);

After initialization, the size of v[0] and v[1] are both 1. When push_back() executed, the vector will be reallocated.

What confuses me is that &v[0] remains the same during the code runs.

Further, what is the meaning of &v and &v[0] which are different? &v[0] is also different from &v[0][0] which is the address of v[0][0].

Last but not least, why are &v[0][0] and &v[0][1] contigous while &v[0] and &v[1] seem not?

Thanks in advance.
Don't confuse the location where the vector object is stored with the location where it stores its elements. Internally the vector contains a pointer to an array of elements.

What confuses me is that &v[0] remains the same during the code runs.

v[0] is a std::vector<int>. Inserting new elements to that vector might affect the location of its elements but not of the vector object itself.

If you instead call push_back on v then you'll see that &v[0] and &v[1] changes (assuming a "reallocation" happens).

what is the meaning of &v and &v[0] which are different? &v[0] is also different from &v[0][0] which is the address of v[0][0].

v is the vector<vector<int>> object.

v[0] and v[1] are the vector<int> objects stored as elements in v.

v[0][0] is the first element of v[0].

Using & in front of an object gives you the memory address (pointer) of that object.

Last but not least, why are &v[0][0] and &v[0][1] contigous while &v[0] and &v[1] seem not?

v[0][0] and v[0][1] belong to the same vector v[0] so they should be stored contiguously (after each other) in memory.

The same should be true about v[0] and v[1]. They both belong to v.
Last edited on
When push_back() executed, the vector will be reallocated.
No, the vectors may be reallocated. Both v[0] and v[1], but not v. I say "may", because the std::vector constructor only guarantees that the capacity will be >= the requested size.

What confuses me is that &v[0] remains the same during the code runs.
Yes, because v is not reallocated. Check &v[0][0] and &v[1][0].

Further, what is the meaning of &v and &v[0] which are different? &v[0] is also different from &v[0][0] which is the address of v[0][0].
&v is the address of the top-level vector v. &v[0] is the address of the first element of v, which is also a vector. &v[0][0] is the address of the first element of the first element (this is not a typo) of v, which is an int.

Last but not least, why are &v[0][0] and &v[0][1] contigous while &v[0] and &v[1] seem not?
v[0] and v[1] are contiguous. What's happening is that sizeof(std::vector<int>) is larger than you're expecting. Try this:
1
2
3
4
5
6
7
8
9
auto a = (uintptr_t)&v[0];
auto b = (uintptr_t)&v[1];
auto c = sizeof(std::vector<int>);
std::cout << c << std::endl;
std::cout << b - a << std::endl;
if (b - a == c)
    std::cout << "They're contiguous!\n";
else
    std::cout << "They're not contiguous!\n";
Last edited on
helios, you probably meant sizeof(std::vector<int>).

The size is probably the same either way but still...
Last edited on
You're right. I'll fix that.
Thanks for all your answers that help me figure it out!
Topic archived. No new replies allowed.