2015-11-12 4 views
3

Следующий код должен удалять повторяющиеся значения в векторе.
Например, если вектор содержит {1,5,3,3}, результат должен быть {1,5,3}.Ошибка отладки. 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 (п);' Перед начиная цикл. –

+0

Оператор [] перегружен, если он не ошибается? – user3322385

+0

Он перегружен, но не выделяет пространство в векторе. –

ответ

5

Ошибка утверждения на самом деле говорит вам, что именно происходит. Ваш вектор имеет нулевой размер, и вы пытаетесь индексировать пустой (который, естественно, будет доступ к вещам за пределами границ).

operator[] не создает элементы на лету для стандартной последовательности, как vector, как, скажем, ассоциативные массивы в некоторых языках или как со случаем std::map. Индекс, который вы переходите на operator[], должен находиться в диапазоне [0, vector.size()) или он будет вызывать эту ошибку за пределами допустимого диапазона при отладке (для проверенных реализаций) или потенциальное нарушение segfault/access в сборке релиза (в основном неопределенное поведение). Это делается по соображениям производительности, поскольку в противном случае требовалось бы разветвление в operator[], и это, как правило, разрушало бы сравнимую с массивом производительность индексирования, которая имеет vector (хотя есть метод at, который бросает, у которого есть ветвь накладных расходов).

Здесь вы хотите размер вектора заранее с помощью конструктора заливки, например:

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

или изменить его размер до доступа к нему с operator[] использованием resize метода:

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 есть еще одна проблема. У этого есть проблема в том, что вы перебираете вектор, как будто его размер не изменяется, но вызывает метод стирания, который уменьшает его размер на каждой итерации. Это также вызовет доступ за пределы диапазона - возможно, вы сможете найти решение в рамках упражнения (я предполагаю, что это упражнение с std::unique будет делать трюк). Первое, что нужно отметить, возможно, состоит в том, что operator[] не создает для вас элементы «на лету».

+0

i изменено vector v; int i, n; v.resize (n); для (я = 0; <п; я ++) { v.push_back (рандов()% 10) } , но я до сих пор вектор подстрочный из ошибки диапазона – user3322385

+1

Существует еще одна проблема в вашем 'removeDup 'функция, хотя один шаг за раз. У этого есть проблема в том, что вы перебираете вектор, как будто его размер не изменяется, но вызывает метод «erase», который уменьшает его размер на каждой итерации. Это также вызовет доступ за пределы диапазона - возможно, вы сможете найти решение в рамках упражнения. Прежде всего, обратите внимание, что здесь 'operator []' не создает для вас элементы «на лету». –

0

Я даю вам другой способ решить эту проблему (U может использовать его). Здесь Вы можете использовать #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; 
Смежные вопросы