C++ primer base container insert

  • 2020-05-17 05:56:09
  • OfStack

C++ primer base container insert

Today, when I was learning C++ basic knowledge, I encountered this problem all the time. Finally, I realized that I didn't have a thorough understanding of "iterator failure after container insert".

The topic is as follows:

Assuming that iv is an vector of int, what is wrong with the following program? How would you modify it?


auto iter = iv.begin();
auto mid = iv.begin() + iv.size() / 2;
while(iter != mid){
 if(*iter == some_val)
  iv.insert(iter, 2 * some_val);
}

The code I initially wrote is as follows:


/*************************************************************************
 > File Name: 9.22.cpp
 > Author: wanchouchou
 > Mail: 200802376@qq.com
 > Created Time: 2014 years 11 month 02 day   Sunday  16 when 34 points 20 seconds 
 ************************************************************************/

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

int main(){
 vector<int> vint = {1,1,1,1,1,3,4,1};
 const int val = 1;
 auto viBegin = vint.begin();
    /* So notice here, if vint.size Less than or equal to 1 Words, viMid = viBegin  So it's not going in while Loop, so we should consider this case separately */
 auto viMid = vint.begin() + vint.size()/2; 
 if(vint.empty()){
  cout << "This vector is empty!" << endl;
  return 0;
 }
 if(vint.size() == 1){
  if(*viBegin == val){
   vint.insert(viBegin, 2 * val);
  }
  goto print;
 }
 
 while(viBegin != viMid){
  if(*viBegin == val){
   vint.insert(viBegin, 2 * val);35   }
  ++viBegin;
 }
 
print:
 auto viEnd = vint.end();
 viBegin = vint.begin();
 while(viBegin != viEnd){
  cout << *viBegin << ", ";
  ++viBegin;
 }

 cout << endl;

}

segmentation faulted appears when running.

Logically speaking, it should be ok, so why would it go wrong? I had forgotten the importance of inserting the container "all iterators fail except end!!" . After the first insert, viBegin and viMid are no longer valid, and all subsequent operations on them are illegal. So we have to re-assign two iterators after every insert. Since the assignment of viMid is troublesome, another method is adopted to record whether the current iterator has reached the midpoint of the container. The code is as follows:


/*************************************************************************
 > File Name: 9.22.cpp
 > Author: wanchouchou
 > Mail: 200802376@qq.com
 > Created Time: 2014 years 11 month 02 day   Sunday  16 when 34 points 20 seconds 
 ************************************************************************/

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

int main(){
 vector<int> vint = {1,1,1,1,3,4,1};
 const int val = 1;
 auto viBegin = vint.begin();
 /* So notice here, if vint.size Less than or equal to 1 Words, viMid = viBegin  So it's not going in while Loop, so we should consider this case separately */
 auto mid = vint.size() / 2;
 if(vint.empty()){
  cout << "This vector is empty!" << endl;
  return 0;
 }
 if(vint.size() == 1){
  if(*viBegin == val){
   vint.insert(viBegin, 2 * val);
  }
  goto print;
 }

 while(distance(viBegin, vint.end()) > mid){
  if(*viBegin == val){
   viBegin = vint.insert(viBegin, 2 * val);
   ++viBegin;
  }
  ++viBegin;
 }

print:
 auto viEnd = vint.end();
 viBegin = vint.begin();
 while(viBegin != viEnd){
  cout << *viBegin << ", ";
  ++viBegin;
 }

 cout << endl;

}

The operation effect is as follows:


wanchouchou@wanchouchou-virtual-machine:~/c++/9.*$ ./9.22
2, 1, 2, 1, 2, 1, 2, 1, 3, 4, 1, 

Thank you for reading, I hope to help you, thank you for your support of this site!


Related articles: