4
votes

The following code is supposed to remove the duplicate values in a vector.
For example, if vector contains {1,5,3,3} the result should be {1,5,3}.

The program starts and I enter the integer n*. However, the program throws the following error:

Debug assertion failed.Program : ...\include\vector line:932 Expression:vector subscript out of range.

When I press retry, visual c++ displays a new window:

"try.exe has triggered a breakpoint".

Then, after I click on continue, another error appears:

Debug Assertion Failed! Program :...\include\vector line:933 expression:"standart c++ libraries out of range" && 0

My code is as follows:

#include <iostream>
#include <vector>
using namespace std;
void removeDup (vector<int>& v);

int main()
{
    vector<int> v;
    int i,n;
    cin>>n;
    for(i=0;i<n;i++){
        v[i]=rand()%10;
    }
    removeDup(v);
    for(i=0;i<n;i++)
    {
        cout<<v[i];    
    }
    system("pause");
}

void removeDup(vector<int>& v)
{
    int i,j,size;
    size=v.size();
    for(i=0;i<size;i++)
    {
        for(j=0;j<size;j++)
        {
            if(v[i]==v[j])
            v.erase(v.begin()+j);
        }
    }
}
2
You have to use either v.push_back(rand()%10); or v.resize(n); before starting the loop.πάντα ῥεῖ
operator [] is overloaded if im not mistaken ?Can Özgen
It's overloaded, but doesn't allocate space in the vector.πάντα ῥεῖ

2 Answers

6
votes

The assertion failure is actually telling you exactly what's happening. Your vector is zero-sized, and you are trying to index an empty one (which is naturally going to access things out of bounds).

operator[] does not create elements on the fly for a standard sequence like vector as with, say, associative arrays in some languages or as with the case of std::map. The index you pass to operator[] must be in the range, [0, vector.size()) or it will trigger this out of range assertion failure in debug (for checked implementations) or a potential segfault/access violation in a release build (basically undefined behavior). This is done for performance reasons as it would otherwise require branching in operator[], and that would typically destroy the array-comparable indexing performance that vector has (though there is an at method which throws which has the branching overhead).

Here you want to size the vector in advance using the fill constructor, ex:

int i,n;
cin>>n;
vector<int> v(n);
...

Or resize it prior to accessing it with operator[] using the resize method:

vector<int> v;
int i,n;
cin>>n;
v.resize(n);

Or use push_backs:

vector<int> v;
int i,n;
cin>>n;
// can use reserve here for a performance boost if desired
// since we know the memory capacity needed in advance.
for(i=0;i<n;i++){
    v.push_back(rand()%10);
}

There is one other issue in your removeDup function. That one has an issue in that you are looping through the vector as though its size doesn't change, but calling an erase method which will reduce its size at every iteration. That will also invoke an out of range access -- there maybe you can figure out the solution as part of the exercise (I'm assuming this is an exercise since std::unique will do the trick). First thing to note here perhaps is that operator[] doesn't create elements for you on the fly.

0
votes

I am giving you another way to solve this.(U may use it). Here you can use #include<set> to remove the duplicate value like the following:

set<int>s;
    s.insert(10);
    int i,n;
    cin>>n;
    for(i=0;i<n;i++){
        s.insert(rand()%10);
    }
    set<int>::iterator ii;
    for(ii=s.begin();ii!=s.end();ii++)
    cout<<*ii;