Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vector: initialization or reserve?

Tags:

c++

vector

I know the size of a vector, which is the best way to initialize it?

Option 1:

vector<int> vec(3); //in .h vec.at(0)=var1;     //in .cpp vec.at(1)=var2;     //in .cpp vec.at(2)=var3;     //in .cpp 

Option 2:

vector<int> vec;     //in .h vec.reserve(3);      //in .cpp vec.push_back(var1); //in .cpp vec.push_back(var2); //in .cpp vec.push_back(var3); //in .cpp 

I guess, Option2 is better than Option1. Is it? Any other options?

like image 964
Ale Avatar asked Jan 19 '12 15:01

Ale


People also ask

What is vector Reserve?

std::vector::reserveRequests that the vector capacity be at least enough to contain n elements. If n is greater than the current vector capacity, the function causes the container to reallocate its storage increasing its capacity to n (or greater).

Does vector insert reserve?

If the allocated memory capacity in the vector is large enough to contain the new elements, no additional allocations for the vector are needed. So no, then it won't reserve memory.

Do you need to initialize a vector?

Unlike static containers like an array, a vector does not need a size to be initialized with.

What is the correct way to initialize vector?

Begin Declare v of vector type. Call push_back() function to insert values into vector v. Print “Vector elements:”. for (int a : v) print all the elements of variable a.


2 Answers

Both variants have different semantics, i.e. you are comparing apples and oranges.

The first gives you a vector of n default-initialized values, the second variant reserves the memory, but does not initialize them.

Choose what better fits your needs, i.e. what is "better" in a certain situation.

like image 123
Sebastian Mach Avatar answered Sep 29 '22 00:09

Sebastian Mach


The "best" way would be:

vector<int> vec = {var1, var2, var3}; 

available with a C++11 capable compiler.

Not sure exactly what you mean by doing things in a header or implementation files. A mutable global is a no-no for me. If it is a class member, then it can be initialized in the constructor initialization list.

Otherwise, option 1 would be generally used if you know how many items you are going to use and the default values (0 for int) would be useful.
Using at here means that you can't guarantee the index is valid. A situation like that is alarming itself. Even though you will be able to reliably detect problems, it's definitely simpler to use push_back and stop worrying about getting the indexes right.

In case of option 2, generally it makes zero performance difference whether you reserve memory or not, so it's simpler not to reserve*. Unless perhaps if the vector contains types that are very expensive to copy (and don't provide fast moving in C++11), or the size of the vector is going to be enormous.


* From Stroustrups C++ Style and Technique FAQ:

People sometimes worry about the cost of std::vector growing incrementally. I used to worry about that and used reserve() to optimize the growth. After measuring my code and repeatedly having trouble finding the performance benefits of reserve() in real programs, I stopped using it except where it is needed to avoid iterator invalidation (a rare case in my code). Again: measure before you optimize.

like image 29
UncleBens Avatar answered Sep 29 '22 01:09

UncleBens