Reputation: 452
If I have a class with dynamic allocaton like std::vector
. How much sense does it make to create an array with elements of that object?
I tested the following:
std::vector<int> array[2];
array[0].push_back(10);
array[0].push_back(20);
array[0].push_back(30);
array[1].push_back(40);
array[1].push_back(50);
array[1].push_back(60);
for (auto x : array[0]) {
std::cout << x << std::endl;
}
for (auto x : array[1]) {
std::cout << x << std::endl;
}
Which outputs the values correctly. However is this actually undefined behavior? Array elements are located contiguously in memory. When a std::vector
object is initialized without specifying size, it doesn't allocate any memory. So when we create an array with two elements, is any memory allocated at all? When we then add new elements to std::vector
are we writing outside of the array bounds?
Upvotes: 1
Views: 84
Reputation: 310990
An object of the type std::vector<int>
has a fixed size that depends on its implementation.
Consider the following demonstrative program.
#include <iostream>
#include <vector>
int main()
{
std::vector<int> array[2];
std::cout << "sizeof( std::vector<int> ) = "
<< sizeof( std::vector<int> )
<< '\n';
std::cout << "sizeof( array = "
<< sizeof( array )
<< '\n';
std::cout << '\n';
array[0].push_back(10);
array[0].push_back(20);
array[0].push_back(30);
array[1].push_back(40);
array[1].push_back(50);
array[1].push_back(60);
std::cout << "sizeof( std::vector<int> ) = "
<< sizeof( std::vector<int> )
<< '\n';
std::cout << "sizeof( array = "
<< sizeof( array )
<< '\n';
}
Its output might look like
sizeof( std::vector<int> ) = 24
sizeof( array = 48
sizeof( std::vector<int> ) = 24
sizeof( array = 48
When you are adding new elements to the vectors their sizes are not changed and correspondingly the array size also is not changed.
The program is well-formed.
The class template std::vector
contains as its data member a pointer to a memory where it places its elements. If there is no enough memory the vector reallocates it. But the size of an object itself of the vector type does not depend on the reallocated memory.
Upvotes: 1
Reputation: 63471
There is no undefined behavior here.
How much sense does it make to create an array with elements of that object?
This is entirely up to you, and your design considerations. It's perfectly fine to have an array of vectors.
So when we create an array with two elements, is any memory allocated at all?
Yes, memory for the array is allocated.
When we then add new elements to std::vector are we writing outside of the array bounds?
std::vector
allocates memory dynamically. A default-constructed vector may or may not allocate memory. This is implementation-dependent. Internally, the vector is probably just holding pointers.
Some implementations may be smarter than this, by switching from a fixed number of elements with no dynamic allocation to using dynamic allocation if the requirements exceed that. std::string
implementations commonly do this, by repurposing the internal pointer storage to hold string data instead.
Note that if you are pushing some number of elements onto a new vector, it's good practice to call reserve
on that vector to avoid unnecessary reallocations as it grows.
Upvotes: 4