2015-11-12 87 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;