Why do I get a segmentation fault for this? - c++

I just want to create a simple C++ struct that has an int index and an int grayValue .The function is given the vector with the gray values. When I try to compile it I get a segmentation fault, does anyone know why? (didn't sort the vector) Thank you.
vector<gray> createStruct( vector<int> grayValues)
{
vector <gray> grayStruct;
for (int i = 0; i<grayValues.size();i++)
{
grayStruct[i].originalIndex= i;
grayStruct[i].grayValue= grayValues[i];
}
return grayStruct;
}
int main() {
vector <int> grayVals={411,21,78,23};
vector <gray> grayStruct=createStruct(grayVals);
// sort(grayStruct);
for (int i = 0; i < grayStruct.size(); i++)
{cout << grayStruct[i].originalIndex<<' '<<grayStruct[i].grayValue;
cout<<endl;
}
return 0;
}

It is because you are using elements of grayStruct, which actually doesn't exist, in the function createStruct.
You have to create elements before use or use push_back() to create elements.
Create elements via the constructor:
vector<gray> createStruct( vector<int> grayValues)
{
vector <gray> grayStruct(grayValues.size()); // add number of elements to create
for (int i = 0; i<grayValues.size();i++)
{
grayStruct[i].originalIndex= i;
grayStruct[i].grayValue= grayValues[i];
}
return grayStruct;
}
Create elements via resize():
vector<gray> createStruct( vector<int> grayValues)
{
vector <gray> grayStruct;
grayStruct.resize(grayValues.size()); // create elements
for (int i = 0; i<grayValues.size();i++)
{
grayStruct[i].originalIndex= i;
grayStruct[i].grayValue= grayValues[i];
}
return grayStruct;
}
Add elements one-by-one via push_back():
vector<gray> createStruct( vector<int> grayValues)
{
vector <gray> grayStruct;
for (int i = 0; i<grayValues.size();i++)
{
gray value;
value.originalIndex= i;
value.grayValue= grayValues[i];
grayStruct.push_back(value); // add an element
}
return grayStruct;
}

Related

Merge Sorted array Error in c++: reference binding to null pointer of type 'int' (stl_vector.h)

https://leetcode.com/problems/merge-sorted-array/
In this leetcode question, this is the logic, I used
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int i = 0;
int j = 0;
int k = 0;
vector<int> ans;
while (i<m && j<n) {
if (nums1[i] < nums2[j]){
ans[k++] = nums1[i++];
}
else {
ans[k++] = nums2[j++];
}
}
while (i<m) {
ans[k++] = nums1[i++];
}
while (j<n) {
ans[k++] = nums2[j++];
}
for (int h = 0; h<(m+n); h++) {
nums1[h] = ans[h];
}
}
};
while running the code, I get this runtime error.
Error Image
How do I solve this
This is a vector of size zero
vector<int> ans;
This code attempts to change an element of the size zero vector.
ans[k++] = nums1[i++];
That's the cause of your error.
If you want to add an element to the end of a vector use push_back
ans.push_back(nums1[i++]);
C++ vectors don't change size automatically, you have to use push_back or resize or insert or something similar.
Alternatively make the vector the correct size to begin with
vector<int> ans(m + n);
though I prefer the push_back method myself.

c++ vector one dimensional and two dimensional arrays value assignment

I am confused about c++ two dimensioanal vectors
#include <vector>
int main()
{
//First Code
std::vector<int> oneDimArray;
oneDimArray.push_back(5);
for (int i = 0; i < oneDimArray.size(); i++)
{
std::cout << oneDimArray[i];
}
//Second Code
std::vector<std::vector<int>> twoDimArray;
twoDimArray[0].push_back(5); //Here giving error
for (int i = 0; i < twoDimArray.size(); i++)
{
for (int j : twoDimArray[i])
{
std::cout << j;
}
}
return 0;
}
when i try to run this code First Code is working. But in Second Code i am getting vector out of range error while trying to push back. I guess at first i should say twoDimArray's first size to it. But i dont know how. Because i am definig this twoDimArray in my .h file so if i do this i must do it there. Please can you help me?
The reason this is happening is because of two reasons.
The vector you are trying to access is empty
You are trying to put an int into a vector that was supposed to hold vector<int>s.
Fixed code:
#include <vector>
#include <iostream>
int main()
{
std::vector<int> oneDimArray;
oneDimArray.push_back(5);
for (int i = 0; i < oneDimArray.size(); i++)
{
std::cout << oneDimArray[i];
}
std::vector<std::vector<int>> twoDimArray;
twoDimArray.push_back(oneDimArray); //You can put a vector of ints in here
for (int i = 0; i < twoDimArray.size(); i++)
{
for (int j : twoDimArray[i])
{
std::cout << j;
}
}
return 0;
}
twoDimArray[0].push_back(5) is invalid because the vector had no size yet. After you have pushed back something, or done twoDimArray.resize(new size here);, then you can do that (as long as it isn't out of range).
Also, once a vector has size, you can access the elements of the vector inside the vector by going like twoDimArray[0][0] = 1;. That would give the first value of the first vector inside of the vector to get the value 1.

Segmentation fault in merge sort code

I have written this merge sort program in c++ but I am getting "Segmentation fault (core dumped)" error after running the code. Even though there is no compilation error. Can you please tell me what's the mistake I am doing? While taking input in the array it is showing that error. If I change it to push_back, the input is fine but later in merge function, it is showing the same error.
//merging 2 sorted subarrays.
#include <iostream>
#include <vector>
using namespace std;
void merge(vector <int> &a,vector <int> &b,vector <int> &c)
{
int i=0,j=0,k=0,bL=b.size(),cL=c.size();
while(i<bL && j<cL)
{
if(b[i]<c[j])
{
a[k]=b[i];
i++;k++;
}
else
{
a[k]=c[j];
j++;k++;
}
}
while(i<bL)
{
a[k]=b[i];
i++;k++;
}
while(j<cL)
{
a[k]=c[j];
j++;k++;
}
cout<<"array a inside merge is: "<<endl;
for(int p=0;p<a.size();p++)
{
cout<<a[p]<<endl;
}
}
void mergeSort(vector <int> &a)
{
vector <int> l, r;
int mid;
if(a.size()<2) return;
mid = a.size()/2;
for(int i=0;i<mid;i++)
{
l[i]=a[i];
}
for(int i=mid;i<a.size();i++)
{
r[i-mid]=a[i];
}
mergeSort(l);
mergeSort(r);
merge(a, l, r);
}
int main()
{
int n;
vector <int> a;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
mergeSort(a);
for(int p=0;p<n;p++)
{
cout<<a[p]<<endl;
}
return 0;
}
Whever you access an element in a vector using [] you might get a seg fault.
This code,
vector <int> a;
gives you an empty vector.
Asking for a[0] won't work if there's nothing in a yet.
Trying to set a[0] to a value won't work either.
It doesn't exist.
Yet.
You have a similar problem in mergeSort when you use
vector <int> l, r;
These are also empty vectors.
You can use push_back (or even emplace_back) to add new elements.
Or use a constructor overload to state how many elements you want.
For example,
vector <int> a(10);
gives you a vector of ten ints, so a[0] is fine to read from or write to.
a[11] isn't.
Practise using a vector first then try your merge sort.
The reason for getting a segmentation fault is you access the location of the memory which does not exist (more accurate to say as not allocated). Say you have a vector of length 3 and you try to access 4th position, you get a segmentation fault.
As opposed to #doctorlove's answer, I would say it is possible to use []. However, you need the following implementation (only shown for main(), please implement with the same logic in the other functions). See the documentation of std::vector for more info.
int main()
{
size_t n;
std::cin >> n;
std::vector <int> a(n);
for(int i=0;i<n;++i)
{
std::cin >> a[i];
}
// mergeSort(a);
for(int i=0;i<n;++i)
{
std::cout << a[i] << "\n";
}
return 0;
}
Hope this helps. Cheers.
here is the final code after changes:
//merging 2 sorted subarrays.
#include <iostream>
#include <vector>
using namespace std;
void merge(vector <int> &a,vector <int> &b,vector <int> &c)
{
int i=0,j=0,k=0,bL=b.size(),cL=c.size();
while(i<bL && j<cL)
{
if(b[i]<c[j])
{
a[k]=b[i];
i++;k++;
}
else
{
a[k]=c[j];
j++;k++;
}
}
while(i<bL)
{
a[k]=b[i];
i++;k++;
}
while(j<cL)
{
a[k]=c[j];
j++;k++;
}
cout<<"array a inside merge is: "<<endl;
for(int p=0;p<a.size();p++)
{
cout<<a[p]<<endl;
}
}
void mergeSort(vector <int> &a)
{
vector <int> l, r;
int mid;
if(a.size()<2) return;
mid = a.size()/2;
for(int i=0;i<mid;i++)
{
l.push_back(a[i]);
}
//change2
for(int i=0;i<a.size()-mid;i++)
{
r.push_back(a[mid+i]);
}
mergeSort(l);
mergeSort(r);
merge(a, l, r);
}
int main()
{
int n;
cin>>n;
//change1
vector <int> a(n);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
mergeSort(a);
cout<<"Final array is:"<<endl;
for(int p=0;p<n;p++)
{
cout<<a[p]<<endl;
}
return 0;
}

unhandled exception access violation reading location / using vector of struct

I face the "unhandled exception access violation reading location", after i searched and realize that the problem reason from using vectors, but still i didn't solve it yet.
in .h i defined the following:
struct inside
{
double y;
vector <int> values;
};
struct outside
{
int x;
vector <inside> subInfo;
vector <double> d;
};
in .cpp:
vector <outside> mainInfo;
....
// method_inti called one time just ...
method_inti()
{
for(int i=1;i<=4;i++)
{
outside obj;
obj.x = i;
mainInfo.push_back(obj);
}
}
....
// method fill called many times (very large number of calls .. )
method_fill()
{
...
for(i = 1; i <= 4; i++)
{
for (int j=0;j< mainInfo.size();j++) // here surly size = 4
{
if(mainInfo[j].x == i)
{
inside obj;
obj.y = i+1;
obj.values.push_back(10.0);
mainInfo[j].d.push_back(5.0);
mainInfo[j].subInfo.push_back(obj);
}
}
}
...
}
// update n val method also called many times..
updateNval_method(int t)
{
double n;
for (int i=0; i< mainInfo.size();i++)
{
if(mainInfo[i].x == t)
{
n= mainInfo[i].d[(mainInfo[i].d.size())-1];
}
}
}
In the line n= mainInfo[i].d[(mainInfo[i].d.size())-1]; you're subtracting 1 from d.size() to get an array index, but you have no guarantee that d.size() >= 1.
If d happens to contain no elements, you're trying to access an array index of -1, which will throw that exception.

Two dimensional array using vector

I want to create 2D array using vector. But, when I do this, I get seg fault.
Can anyone please explain what I am doing wrong, and possible solution for this problem.
I made everything public since I dont want to deal with getters and setters now.
I want to get the concept of 2D array clear.
#include <iostream>
#include <vector>
using namespace std;
class point
{
public:
point():x(0),y(0){}
~point(){}
point(float xx,float yy):x(xx),y(yy){}
float x,y;
};
int main()
{
vector<vector<point> > a; // 2D array
point p(2,3);
a[0][0] = p; // error here
return 0;
}
Your vector is empty. So you can't use [0][0].
Here is how you declare it:
a.push_back(vector<point>());
a[0].push_back(p);
If you know how many items you will have from the start, you can do :
vector<vector<point> > a(10, vector<point>(10));
It's a vector containing 10 vectors containing 10 point. Then you can use
a[4][4] = p;
However, I believe that using vector of vectors is confusing. If you want an array, consider using uBLAS http://www.boost.org/doc/libs/1_41_0/libs/numeric/ublas/doc/index.htm
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
int main () {
using namespace boost::numeric::ublas;
matrix<double> m (3, 3);
for (unsigned i = 0; i < m.size1 (); ++ i)
for (unsigned j = 0; j < m.size2 (); ++ j)
m (i, j) = 3 * i + j;
std::cout << m << std::endl;
}
Here's another suggestion. What you're trying to accomplish has been done before and can be found within the Boost Multi-Array.
You have constructed a vector of vectors that is empty, and have tried to dereference the first element without adding any elements to it.
Vectors don't work like (some) associative arrays, where attempting to access a value that's missing will add it to the collection. You need to ensure the vectors have an appropriate number of entries before you try to access them by using the appropriate form of the vector constructor or by using push_back.
You're creating your 2D array just fine. The problem is that when you create it, it's an empty array -- it doesn't hold any points at all yet. You try to use the point at [0][0] before you've actually created a point there. Normally, to put a new element into a vector, you use resize() to set the size of the vector, or push_back() to add items one at a time. In this case, the latter will probably be a bit clumsy -- since you have a vector of vectors of point, you need to create a vector of point, push a point onto that vector, then push that vector onto your array.
The simplest way would be to use resize() method as follow:
vector <vector<int>> v;
cin>>n>>m; //n is rows and m is columns
v.resize(n,vector<int>(m));
for(i=0;i<n;i++) // inserts elements into the vector v
for(j=0;j<m;j++)
cin>>v[i][j];
for(i=0;i<n;i++) //accesses elements of vector v
for(j=0;j<m;j++)
cout<<v[i][j]<<" ";
Managed to get it working. Picked up the idea for the 'typedef' from somewhere else. Try the below code, it works:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
using namespace std;
int main()
{
int i = 0;
int j = 0;
///////////////////////////////////////////////////////////
typedef vector<string> vecRow;
typedef vector<vecRow> vecCol;
vecRow vr;
vecCol vc;
///////////////////////////////////////////////////////////
// Assigning string elements to the 2d array
for(i=0;i<10;i++)
{
for(j=0;j<5;j++)
{
vr.push_back("string ["+to_string(i)+"]["+to_string(j)+"]");
}
vecRow vr_temp = vecRow(vr);
vc.push_back(vr_temp);
vr.clear();
}
///////////////////////////////////////////////////////////
// Printing back the elements from the 2D array
for(auto element : vc)
{
for(unsigned int ictr = 0;ictr < element.size() ; ictr++)
{
cout<<element[ictr]<<"\t";
}
cout<<endl;
}
getchar();
return 0;
}
You can define vectorMatrix[][], which is a matrix of vectors as follows.
Class:
class vectorMatrix
{
std::vector<object> **cell;
int columns;
int rows;
public:
vectorMatrix(int columns, int rows);
virtual ~vectorMatrix();
void addCellAt(int row, int column, const object& entry);
virtual std::vector<object>* getCell(int row, int column);
void clearMatrix();
};
Define constructor:
vectorMatrix::vectorMatrix(int columns, int rows)
{
this->columns = columns;
this->rows = rows;
cell = new std::vector<object>* [columns];
for (int i = 0; i < columns; i++)
{
cell[i] = new std::vector<object>[rows];
}
}
A method for adding an entry:
void vectorMatrix::addCellAt(int row, int column, const object& entry)
{
cell[channel][timeSlot].push_back(entry);
}
Getting a pointer to the vector in a given row and column:
std::vector<object>* vectorMatrix::getCell(int row, int column)
{
return &cell[row][column];
}
Clearing all the matrix:
void vectorMatrix::clearMatrix()
{
for (int tmpRow = 0; tmpRow < columns; tmpRow ++)
{
for(int tmpColumn = 0; tmpColumn < rows; tmpColumn ++)
{
cell[tmpRow][tmpColumn].clear();
}
}
}
You can use resize(); e.g., here I resize a to a 100 x 200 array:
vector<vector<point> > a; // 2D array
a.resize(100);
for_each(a.begin(),a.end(),[](vector<point>& v){v.resize(200);});
point p(2,3);
a[0][0] = p; // ok now