2015-11-12 86 views
3

下面的代码应该删除向量中的重复值。
例如,如果载体包含{1,5,3,3},结果应该是{1,5,3}Debug断言失败.. C++向量下标超出范围

该程序启动,我输入整数n*。 然而,该程序引发以下错误:

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

当我按下重试,VISUAL C++显示一个新的窗口:

"try.exe has triggered a breakpoint".

然后,在我点击继续,出现另一个错误:

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

我的代码如下:

#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

您可以选择使用'v.push_back(兰特()%10);'或'v.resize(N);'前开始循环。 –

+0

如果我没有弄错,operator []是否超载? – user3322385

+0

它已超载,但未在矢量中分配空间。 –

回答

5

断言失败实际上告诉你到底发生了什么。你的向量是零大小的,你试图索引一个空的索引(这自然会访问超出范围的东西)。

operator[]并不像vector那样为标准序列创建元素,例如某些语言中的关联数组,或者与std::map的情况一样。您传递给operator[]的索引必须在范围[0, vector.size())之内,否则它会在调试(对于检查的实现)中触发该范围断言失败或在发布版本(基本上未定义的行为)中触发潜在的段错误/访问冲突。这是出于性能原因,因为否则它需要在operator[]中分支,并且这通常会破坏vector具有的阵列可比索引性能(尽管存在引发分支开销的at方法)。

在这里,您使用的填充构造希望的大小提前载体,例如:

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

或者使用resizeoperator[]来访问它之前调整其大小:

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

或者使用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); 
} 

您的removeDup功能还有一个问题。那个问题在于你正在遍历vector,就好像它的大小没有改变一样,但是调用了一个擦除方法,在每次迭代时都会减小它的大小。这也将调用超出范围的访问 - 也许你可以找出解决方案作为练习的一部分(我假设这是一个练习,因为std::unique将做到这一点)。此处首先要注意的是,operator[]不会为您即时创建元素。

+0

i changed vector v; int i,n; v.resize(n); 为(I = 0; I user3322385

+1

的有在'removeDup一个其它问题'功能,尽管一步一个脚印。那个问题在于你正在遍历vector,就好像它的大小没有改变一样,但是调用一个'erase'方法,每次迭代都会减小它的大小。这也将调用超出范围的访问权限 - 也许你可以将解决方案作为练习的一部分 - 首先要注意的可能是运算符[]'不会为您即时创建元素。 –

0

我给你另一种方法来解决这个问题(你可以使用它)。 在这里,您可以使用#include<set>删除喜欢重复的值如下:

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;