Debug assertion failed.. C++ vector subscript out of range - c++

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);
}
}
}

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.

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;

Related

Why are vectors' size static and we still can add more values?

I'm a complete beginner to C++ but I have some basics knowledge in programming (Python mainly) and I'm trying to learn C++. As the question implies, vectors have static sizes (at least what I've read in my learning material) but we still can add more values to what the size authorize. I wrote a simple code to know what error I get if I pass more values to a vector than the limit authorized by it's size and surprisingly I didn't get any error.
The code are these simple lines:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int it=0,a;
vector<int> v(10);
for(a=1; a<21; a++)
{
v[it]=x;
cout << v[it] << endl;
it++;
}
cout<<"Values stored in v";
for(i=0;i<it;i++)
cout<<v[i]<<" ";
cout<<endl;
cout<<"Vector's size : "<<v.size()<<endl;
return 0;
}
What I get with cout<<"Values stored in v"; are all values from 1 to 20, but I still get that the size is 10.
If that can helps I'm on Windows 10 x64 and using Qt Creator compiler.
What is fixed is
sizeof( vector<int> )
A vector can contain varying number of elements, but that elements are stored on the heap, hence do not contribute to the vectors sizeof. The number of elements is v.size() (and that can change).
You create a vector with 10 elements:
vector<int> v(10);
But then you attempt to access elements that do not exist in the loop. For example v[10] will not cause a compiler error, it is also not guaranteed to cause a runtime error. Nevertheless, it is guaranteed wrong. Accessing the vector out of bounds causes undefined behavior. The output of the code could be anything.

Why starting for loop at i=1 giving me segmentation fault in this vector problem?

I am trying to create a variable sized array which will help me store values and will allow me to retrieve and print the value as query asks. I actually completed this problem but as I am new to coding part, I just wanted to ask why using for loop starting from i=1 to i<=n gives me segmentation fault?
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n, n1, data, q1, q2, q; /*n is number of variable length arrays and q is queries*/
cin>>n>>q;
vector< vector<int> > a(n); //vector as suited for to take input in number of arrays required
for(int i=1;i<=n;i++)
{
cin>>n1; //number of element in first array index
for(int j=1;j<=n1;j++)
{
cin>>data;
a[i].push_back(data);
}
}
for(int i=1;i<=q;i++)
{
cin>>q1>>q2; /*taking input queries as array index and then inside that second query pointing to variable array elements*/
cout<<a[q1][q2]<<endl;
}
return 0;
}
When you declare a vector like this:
vector< vector<int> > a(n);
it has size n. Indexing in c++ (and in fact, most programming languages), starts from 0 and goes to n-1.
If you index into a vector of size n with the index n (as you are doing in your for loop), this is an out of bounds index, and invokes undefined behavior. The result of undefined behavior is that the program can do anything. A segmentation fault is actually a good result, since you can fix the bug before anything too unpleasant happens.
You can also try indexing into a vector with .at(). This is also wrong, but it's a different kind of wrong; it's defined behavior, and it's defined to throw a std::out_of_range exception telling you exactly what you did wrong.
When you first declared the vector, you gave it n elements, which are from 0 to n - 1. However, in your for loop, i can reach upto n, which causes a segmentation fault (or vector subscript out of range) when you try to modify a[i], since it doesn't exist yet.

Vector <int> input and output

I am stuck with simple vector input and output operations. The compiler returns error saying 'std::outof range'
Here is the code
int main()
{
int size;
cout <<"Enter size of vector\n";
cin>>size;
cout<<"Now to input the vector of size "<<size<<endl;
vector <int> trial;
for (size_t i=0;i<size;++i){
int x;
cout<<"write at position"<<trial.at(i)<<'t';
cin>>x;
trial.push_back(x);
cout<<endl;
}
ostream_iterator<int> output(cout,"");
copy(trial.begin(),trial.end(),output);
}
I would appreciate a brief explanation of the internal workings of the problem.
You invoke trial.at(i) before trial.push_back(x), accessing a not yet existing element. Since the element doesn't (yet) exist, i is an invalid index, and at() will throw a std::out_of_range exception when passed an invalid index. If an exception isn't caught, it will terminate the program. Presumably your platform's runtime library displays the exception that caused the program to be terminated.
I suppose what you actually want is this:
std::cout << "write at position " << i << '\t';
Consider the first iteration of this loop:
vector <int> trial;
for (size_t i=0;i<size;++i){
int x;
cout<<"write at position"<<trial.at(i)<<'t';
At the first iteration nothing has been pushed into the vector, so trial.at(0) isn't yet valid. The result will be an exception. Since you don't have a try/catch anywhere, that will end your program's execution.
It looks to me like you want cout << "write at position " << i; instead. i is the position; after it has been pushed onto the vector so it's valid, vector.at(i) will be the value at that position.
trial.at(i)
You're accessing an element that doesn't exist.
You probably want cout<<"write at position"<< i <<'t'; anyway.
The problem is this line:
cout<<"write at position"<<trial.at(i)<<'t';
You call this before you have set the size of the vector. I'm not really sure what that line is trying to accomplish anyway. If you're trying to print the in memory position (address) that won't do it, if you're trying to print what was already there then it would work if it had already been allocated. Using vector::push_back() means that you don't need to preallocate though.
You can fix this by resizing the vector and accessing the elements directly like this:
trial.resize(size);
// loop
// vector.push_back(x) -- now becomes
vector[i] = x;
Or, you can simply remove the printing of the position and use push_back() as you are now.
Since it seems you're investigating how to use vector I would suggest trying to gain an understanding of how the push_back() and resize() methods differ, and have also have a look at the vector::reserve() function.

stl map, set error: memory clobbered past end of allocated block

As I tried to solve this interview problem: find the sum of continuous element in an array which equals to a target number, so I come up with the following code. However, I really don't understand why it has some memory allocation problem. Here is the link to the full code. when I tried to insert the second element of currSum into the set and map, it will have some error message like "memory clobbered past end of allocated block". Isn't set, map dynamically allocated for insert? I really don't understand why it's not working as I think.
I also paste the full code here:
#include <map>
#include <set>
#include <iostream>
using namespace std;
void print_array(int arr[], int start, int end)
{
for(int i=start;i<=end;i++)
cout<<arr[i]<<" ";
cout<<endl;
}
//given an array, find the continous sum of the array which is a target number
void findTargetSum(int arr[], int target, int sizeArr)
{
map<int, int> valIdxMap;
set<int> prevSet;
int* currSum= new int(sizeArr+1);
currSum[0]=0;
for(int i=1;i<=sizeArr;i++)
{
currSum[i]=currSum[i-1]+arr[i-1];
}
//now the problem is to find two elements i, j in array currSum,where currSum[j]-currSum[i]=target && j>i
for(int i=0; i<=sizeArr;i++)
{
int tmp=currSum[i]-target;
set<int>::iterator iter=prevSet.find(tmp);
if (iter !=prevSet.end())
{
cout<<"located one range of array elements with sum to"<<target<<endl;
int startIdx=valIdxMap[*iter];
print_array(arr,startIdx,i-1);
}
else
{
prevSet.insert(currSum[i]);
valIdxMap.insert(make_pair(currSum[i],i));
}
}
delete currSum;
}
void testfindTargetSum()
{
int tst_arr[]={2,4,5,-1,3,8};
int target=11;
findTargetSum(tst_arr,11,6);
}
int main()
{
testfindTargetSum();
return 1;
}
The error is in this line:
int* currSum= new int(sizeArr+1);
That line acquires a single int and initializes it to the value sizeArr+1. You probably meant:
int* currSum= new int[sizeArr+1];
That will acquire a block of sizeArr+1 elements of type int. Additionally you will have to change the line delete currSum; to be delete [] currSum;.
My advice, on the other hand, would be not to manage memory manually but use a standard container, for example:
std::vector<int> currSum( sizeArr+1 );
Will basically be an in-place replacement for your current implementation and it will manage memory automatically.
As of the implementation, I believe that you can actually do it without any extra memory in O(N) by accumulating the start index, end index and sum of the values in three variables while iterating. While the accumulated value is smaller than the target, increment the end index and add the value. When the accumulated value grows higher than the target, increment the start index and decrement the accumulated value by that amount.
you wrote
int* currSum= new int(sizeArr+1);
you probably meant
int* currSum= new int[sizeArr+1];

While inserting nodes in heap how to use bubble up?

Following is my code which doesnot properly bubbles up the larger value .Can any one help out .The problem is somewhat at count++ .
#include<iostream>
using namespace std;
class heap{
public:
int count;
heap(int c)
{
count=c;
}
int Arr[10];
void insert(int num);
void deletemax();
void print();
};
void heap::insert(int num){
if(count==10){
cout<<"Heap full\n";
exit(1);
}
else{
Arr[count]=num;
count++; //The real problem arises here that the compiler adds 1 to count and when the code moves ahead it sets position var to count++ value and tries to compare a value at Arr[POS] with its parent whereas there is no value at this place set uptill.
}
int POS=count;
while(Arr[POS]>Arr[(POS-1)/2]){
int temp;
temp=Arr[POS];
Arr[(POS-1)/2]=temp;
POS=(POS-1)/2;
}
}
void heap::print(){
for(int i=0; i<10; i++){
cout<<Arr[i]<<endl;
}
}
int main(){
heap h(0);
int a;
int b=0;
while(b<10){
cout<<"Insert node in heap\n";
cin>>a;
h.insert(a);
b++;
}
h.print();
return 0;
}
I would agree, that's where your problem is.
There are many issues with the code you posted, some of which include:
As to your specific issue, I would guess you need to change the line in heap::insert() to "int POS=count-1;" to properly start iterating from the back of the array.
You need to consider the case of adding an element to an empty array and what then happens in your sorting code.
Your constructor allows someone to create a heap that will overflow the fixed sized array, for example heap(1000). In addition, the Arr member is not initialized which means it has undefined data for any value but heap(0). In this case your constructor should not take any parameters and count should just be initialized to 0.
The purpose of the code is confusing. Is it a heap, a sorted array, an attempt to approximate a heap with an array, none of the above? If you are simply trying to implement a fixed sized sorted array then I believe your sorting code in insert() will not work (e.g., consider adding 100 to a heap containing [1,2,3]).
There are other, more basic things, wrong (like not using any the STL containers, public class member, non-const parameter passing, "using std", etc...) but I'm assuming you are merely experimenting/playing here.