Actually the essence of the problem:

When executed, it gives an error:

Expression: vector iterator not incrementable. See the Visual C ++ documentation on asserts.

The problem in this line: arr.erase(it);
How to fix this error?

 void DeleteZeros(std::vector<int>&arr) { for (std::vector<int>::iterator it = arr.begin(); it != arr.end(); ++it) { if (*it == 0) { arr.erase(it); } else { std::cout << "asdasdasd"<< std::endl; } } } 

Code:

 #include "stdafx.h" #include <iostream> #include <vector> #include <algorithm> #include <iterator> //using namespace std; void MakeArr(std::vector<int>&arr) { for (int i = 0; i < arr.size(); i++) { arr[i]= rand() % 10; } } void show_vector(std::vector<int>&a) { for (std::vector<int>::iterator it = a.begin(); it != a.end(); ++it) std::cout << *it<<" "; } int*GetFreq1(int*arr, int size) { int*FreqArr=new int[size]; for (int i = 0; i < size; i++) { int Count = 1; for (int j = i + 1; j < size; j++) { if (arr[i] == arr[j]) { Count++; FreqArr[j] = 0; } } if (FreqArr[i] != 0) { FreqArr[i] = Count; } } std::cout << "\n Frequency of All the Elements in this Array are : \n" << std::endl; for (int i = 0; i < size; i++) { if (FreqArr[i] != 0) { std::cout << arr[i] << "occurs" << FreqArr[i] << "times" << std::endl; } } return FreqArr; } void DeleteZeros(std::vector<int>&arr) { for (std::vector<int>::iterator it = arr.begin(); it != arr.end(); ++it) { if (*it == 0) { arr.erase(it); //iterator is not incrementable //std::cout << "blyaa"; } } } int main() { int n; std::cout << "input count of elements :"; std::cin>>n; std::vector<int>arr(n); std::vector<int>n_i(n); MakeArr(arr); show_vector(arr); std::sort(arr.begin(), arr.end()); //variazijnyj ryad std::cout <<std::endl<<"Sorted Arr :" << std::endl; show_vector(arr); //n_i=getFreq(arr, n); int*sss = new int[n]; int*atatat = new int[n]; for (int i = 0; i < arr.size(); i++) { atatat[i] = arr[i]; } sss = GetFreq1(atatat, n); for(int i=0;i<arr.size();i++) { n_i[i] = sss[i]; } //std::unique(arr.begin(), arr.end());// building a table std::cout << "\n Ni table: " << std::endl; show_vector(n_i); DeleteZeros(n_i); show_vector(n_i); system("pause"); return 0; } 
  • You could get the same result in several lines. It seems that you specifically tried to write harder - AR Hovsepyan

3 answers 3

In fact, when executing arr.erase(it) iterator is arr.erase(it) and you cannot continue working with it, which is what erase() describes :

Invalidates iterators and references, including the end() iterator.

To understand - imagine the situation when you delete a single element of the vector - immediately after that, even if there is no transfer of elements, you will get what the iterator already points to for the array - in arr.end() . And you are going to increase it, and then compare it with arr.end() - firstly, it will not be equal, and you will get an infinite loop, and secondly, you will start checking elements further and further beyond the array boundaries ... So clearer?

In addition, erase() one element at a time is expensive.

So replace the incorrect solution with, for example, this - using the standard remove() algorithm:

 void DeleteZeros(std::vector<int>&arr) { arr.erase(remove(arr.begin(),arr.end(),0),arr.end()); } 

    This is not the answer to the question you asked, but I really wanted to note that you need to choose the path easier when writing codes, using more tools provided by the standard. For example, you can simplify all your code to this:

     int n; std::cout << "input count of elements : "; std::cin>>n; std::vector<int>arr(n); for (int& i : arr) i = rand() % 10; std::map<int, int> m_i; for (const int i : arr) { std::cout << i << ' '; m_i[i]++; } std::cout << std::endl; std::cout << "\n Frequency of All the Elements in this Array are : \n\n"; for (auto p : m_i) std::cout << p.first << " occurs " << p.second << " times\n" ; std::cout << " Ni table: \n"; for (auto p : m_i) std::cout << p.second <<' '; 

    Without any difficulties with the definitions of functions and the figuring of arrays. Here, of course, you can still reduce the number of lines, if you use standard algorithms and lambda expressions, but this option is not worse ...

    • Thank! I originally wrote under the arrays, and then for the STL remembered) - Awesome Man

    By itself, you get an error, look here:

     for (std::vector<int>::iterator it = arr.begin(); it != arr.end(); ++it) { if (*it == 0) { arr.erase(it); 

    see, you delete an iterator, and then what? And then you take it, and you increase it in for , do ++it

    To fix it, do it (checked):

     void DeleteZeros(std::vector<int>&arr) { for (std::vector<int>::iterator it = arr.begin(); it != arr.end();) { if (*it == 0) { arr.erase(it); } else { ++it; } } } 

    Thus, after deleting for will be possible to check whether the iterotor can be increased (if you don’t point it to the end). True, if you delete several, not one, it will still lead to a problem.