Function of C++ vector.reserve method

1. Push in vector_ Back operation

push_ The function of back is to add a new element at the end of the vector. The content of val is copied (or moved) to the new element.
This effectively increases the container size by 1. If and only if the size of the new vector exceeds the current vector capacity, the new storage space will be reallocated automatically.
Tips:

  • std::vector::size()
    vec.size() returns the number of elements in vec.
  • std::vector::capacity()
    vec.capacity() returns the amount of space allocated by vec in memory.

push_back operation demo1:

//code1

#include <iostream>
#include <vector>
using namespace std;

#define MAX_NUM 9

int main(){
	vector<int> vecInt;
	
	for(int i = 0; i != MAX_NUM; i++){
		vecInt.push_back(i);
	}
	/**
	  some code
	*/
	vecInt.push_back(123);

	for(int i : vecInt){
		cout << i << " ";
	}
	
	return 0;
}
// 0 1 2 3 4 5 6 7 8 123

The above code first declares a vector storing int type, and then increments i by push_back to vecInt. Then add an element to vecInt.

push_back operation demo2:
iterator traverses vector

//code2

#include <iostream>
#include <vector>
using namespace std;

#define MAX_NUM 9

int main(){
	vector<int> vecInt;
	
	for(int i = 0; i != MAX_NUM; i++){
		vecInt.push_back(i);
	}

	vector<int>::iterator iter = vecInt.begin();
	cout << "the 1st element: " << *iter << endl;
	
	vecInt.push_back(123);
	
	while(iter != vecInt.end()){
		cout << *iter << " ";
		iter++;
	}
	
	return 0;
}
/*
the 1st element: 0
0 1 2 3 4 5 6 7 8 123
*/

Pushing vector with for_ After back, an iterator is initialized to point to the begin position of vecInt and print the verification. Then push_back adds an element 123 at the end of the vector, and then iterates vecInt with iter.

push_back operation demo3:
Here's MAX_NUM is modified to 8

//code3
#include <iostream>
#include <vector>
using namespace std;

#define MAX_NUM 8 	// MAX_NUM is changed to 8, and no changes are made in other places

int main(){
	vector<int> vecInt;
	
	for(int i = 0; i != MAX_NUM; i++){
		vecInt.push_back(i);
	}

	vector<int>::iterator iter = vecInt.begin();
	cout << "the 1st element: " << *iter << endl;
	
	vecInt.push_back(123);
        cout <<"vecInt's capacity: " << vecInt.capacity() << endl;
	
	while(iter != vecInt.end()){
		cout << *iter << " ";
		iter++;
	}
	
	return 0;
}
/*
the 1st element: 0
vecInt's capacity: 16
-17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -784369068 805499525 0 1 2 3 4 5 
6 7 123
*/

Only Max was modified_ The value of num is consistent with others. When running the program again, the program exception.
Cause analysis
One of the biggest differences between vector and array is that there is no need to declare the size of vector during initialization. If the size of the vector is not specified during initialization, the size allocated for the vector in memory will be 2 - > 4 - > 8 - > 16 respectively according to the actual usage
When Max_ When num is 8, push in the for loop_ After back, the size of vecInt in memory is 8. Push vecInt 123 again_ Back, the new vector size will exceed the current vector size, so the storage space will be reallocated automatically.
Since the storage space of the vector has been reallocated, in the push_ After back123, iter naturally points to an unknown space, so the program exception.

2. Function of vector reserve

To avoid pushing in the vector_ During the back process, the memory will be automatically reallocated. Vector provides the reserve function.
reserve changes the capacity of the vector so that the vector can hold at least n elements.
If n is greater than the current capacity of the vector, reserve will expand the capacity of the vector_ When the number of back elements is greater than N, a new space of 2n will be reallocated, and then the original n elements will be put into the newly opened memory space. In other cases, the storage space of the vector will not be reallocated.
Demo: compare the difference between using reserve
Note: two vector s are declared in main, vecInt is the default initialization, and vecIntB is initialized with capacity, with a capacity of 100. Perform the same operation for vetIntA and vecIntB respectively:
① Push 0 ~ 99 in turn_ Back to vector,
② In push_ During the process of back, observe whether the capacity of the vector changes.

#include <iostream>
#include <vector>
#include <stdint.h>
using namespace std;

void growPushBack(vector<int> &vec, uint16_t size){
	for(int i = 0; i < 100; i++){ 
		vec.push_back(i);
		if(size != vec.capacity()){
			size = vec.capacity();
			cout << "Capacity changed: " << size << endl;
		}
	}
}
int main(){
	uint16_t sz = 0;
	vector<int> vecIntA;
	sz = vecIntA.capacity();
	//After declaring the vector, you do not use reserve, but directly push_back operation 
	cout << "Making vecIntA growing:" << endl;
	growPushBack(vecIntA, sz);
	
	cout << "\n========separator========\n" << endl;
	
	vector<int> vecIntB;
	sz = vecIntB.capacity();
	//After declaring vecIntB, execute it with reserve, and its capacity is 100 
	vecIntB.reserve(100); 
	cout << "Making vecIntB growing: " << endl;
	growPushBack(vecIntB, sz);
	
	return 0;
}
/*
Making vecIntA growing:
Capacity changed: 1
Capacity changed: 2
Capacity changed: 4
Capacity changed: 8
Capacity changed: 16
Capacity changed: 32
Capacity changed: 64
Capacity changed: 128

========separator========

Making vecIntB growing:
Capacity changed: 100
*/

Demo run result analysis:
If a vector uses the default capacity, it is pushed_ During the back operation, the space will be dynamically and automatically allocated according to the number of added elements, with 2^n increasing; If the capacity(size_type n) is explicitly used to specify the capacity of the vector when declaring the vector, then push_ During the process of back (the number of elements does not exceed n), vector will not automatically allocate space.

Posted by mikster on Mon, 22 Nov 2021 08:44:30 -0800