*** stack smashing detected *** because of 2d vector - c++

char m[2];
vector< vector<tuple<long int, long int>> > f(3);
for(i=0; i<M; i++){
scanf("%s %ld %ld", m, &n, &c);
if(m[0]=='1'){ //f--> 1
f[m[1]-65].push_back(make_tuple(c, n)); //turn ascii to number
m1+=cost;
}
..... //irelevant to f
}
I am having this piece of code and I am facing this problem :
f is supposed to be a 2d-vector of vectors of tuples.
I know I need 3 rows in f but I don't know the numbers of elements in each row (that's why I have a vector).
I thought that putting that 3 defines that I want 3 rows. But it seems like something is wrong : when I have testcase where f[0] or f[1] or f[2] has to hold more than two elements I am getting this error message : *** stack smashing detected ***: <unknown> terminated Aborted (core dumped).
If in the other hand I remove, that 3 completely : vector< vector<tuple<long int, long int>> > f I am getting a seg fault and I suppose it has to do with the fact that I am accessing with f[m[1]-65] a row that does not yet exist?
So the thing is , I need to be able to seperate my input according to m and I know that m[0] = {1,2,3} so I am using that to get m[0] - 65 = {0,1,2} as indexes and fill those 3 vectors. Can you help me get through this?

Related

which part of code is creating Segmentation Fault in hackerrank?

I am trying to solve this problem in hackerrank.
https://www.hackerrank.com/challenges/circular-array-rotation/problem
Every other test is fine but one test is creating Segmentation Fault. This is the test case:
https://hr-testcases-us-east-1.s3.amazonaws.com/1884/input04.txt?AWSAccessKeyId=AKIAR6O7GJNX5DNFO3PV&Expires=1648127766&Signature=a0c1UvQ4t9DBn%2Fkr02ZnLUurhjk%3D&response-content-type=text%2Fplain
I wish to what part of my code is creating Segmentation Fault and I want to know the way to solve it with code and some explanation well as I believe my code should not have created any. Here is my code:
vector<int> circularArrayRotation(vector<int> a, int k, vector<int> queries) {
rotate(a.begin(),a.begin()+a.size()-k,a.end());
vector<int> result;
cout<<result.size()<<endl;
for(auto x:queries) result.push_back(a[x]);
return result;
}
This is the code I am submitting in the hackerrank solution. Please help me to pass the test.
The problem is:
rotate(a.begin(),a.begin()+a.size()-k,a.end());
According to the problem statement, the constraints are:
1 <= n <= 10^5
1 <= k <= 10^5
There is no constraint that k <= n, and the test case you got there is exactly the hit, n = 515, k = 100000.
So the problem is:
a.begin()+a.size()-k // a.size()-k, when k > n, is negative
So the hackerrank compiler has a problem while it's doing a.begin() - negative num.
For fixing that you should make sure it won't go in negative bounds, and since it's a circular rotation one full rotation or 1000 full rotations won't change anything, only the remainder matters:
rotate(a.begin(), a.begin() + a.size() - (k % a.size()), a.end());
It passes all the test cases.

*** Error in `': free(): invalid next size (fast): 0x0000000000667890 ***

This was a function that i made, it calculated Fibonacci Numbers, but when I run it i get the following error
Error in `': free(): invalid next size (fast): 0x0000000000667890
int fib(int n) {
int fibn=0;
std::vector<int> x{0,1};
for(int i = 2 ; i <= n ; i++)
{
x[i]=x[i-2]+x[i-1];
}
fibn=x[n];
return fibn;
}
std::vector<int> x{0,1};
You have a vector with two elements. Valid indices are 0 and 1.
for(int i = 2 ; i <= n ; i++)
{
x[i]=x[i-2]+x[i-1];
}
After the first iteration, you access x[2] and beyond which is outside the bounds of the vector. The behaviour of the program is undefined.
You don't need to store the series in a vector since you're only returning the last value. You only need to store the last two values.
Your vector x only has 2 elements, but your loop starts by setting i to 2 and then does x[i] (aka x[2]) on the first iteration, which is out of bounds since only the indices 0 and 1 are valid.
Remember that array indices start at 0 in C++.
Accessing out of bounds is Undefined Behaviour and as a result your entire program is invalid and the compiler is not required to generate anything sensible, nor is it obliged to tell you about your error.

Segmentation fault while taking input in a 2d array in C++

The computer is giving segmentation fault whenever I try to read input into this. My input looks like:
7
1 2 3
2 3 1
1 4 4
4 6 7
7 5 2
3 5 1
4 5 5
Basically, I want to store the above input directly into a 2D array. The first column is X-coordinates, 2nd column Y-coordinate and finally the value needed to store in (X,Y) COORDINATE of a 2D array.
long leastTimeToInterview(int n, int k, int m) {
int a[m+1][m+1];
int i=0,x=0,y=0;
for (i=1;i<=m;i++){
scanf("%d %d",&x,&y);
scanf("%d",&a[x][y]);
a[y][x]=a[x][y];
}
return 11;
}
Like rustyx mentioned, this error could be a result of a stack overflow.
The easiest aproach would be to reduce the size of your array or use another data structure which allocates memory dynamically like std::vector, std::list or std::map.
In your example it also looks as if most of your array is empty. In this case i sugest using std::map.
Some other optimisations in regard of memory usage are discussed in this question: Any optimization for random access on a very big array when the value in 95% of cases is either 0 or 1?
There is no such thing as dynamically sized array in C++'s type system so you need to change it to somthing else like std::vector. The other problem is that even if your compiler supports dynamically sized arrays you still get stack overflow (at least it's very likely). So I suggest that you change your function to something like this:
long leastTimeToInterview(int n, int k, int m) {
std::vector<std::vector<int>> a(m + 1, std::vector<int>(m + 1));
int i = 0, x = 0, y = 0;
for(i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
scanf("%d", &a[x][y]);
a[y][x] = a[x][y];
}
return 11;
}
There still might be an error in the logic of your application but your example and explanation don't give enough information to tell that.

Does anyone know how to solve problems on variable length arrays?

Input Format
The first line contains two space-separated integers denoting the respective values of (the number of variable-length arrays) and (the number of queries).
Each line of the subsequent lines contains a space-separated sequence in the format k a[i]0 a[i]1 … a[i]k-1 describing the -element array located at.
Each of the subsequent lines contains two space-separated integers describing the respective values of (an index in the array ) and (an index in the array referenced by ) for a query.
Output Format-
For each pair of and values (i.e., for each query), print a single integer denoting the element located at an index of the array referenced by. There should be a total of lines of output.
Sample Input
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Sample Output
5
9
Somebody has solved this problem by -
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n,q; //n number of variable lenght arrays
// q no of queries asked
cin >>n >>q;
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j];
for (int y=0;y<j;y++)
cin>>Vectors[i][y];
}
int q1,q2;
for (int i=0;i<q;i++)
{
cin >>q1 >> q2;
cout<<Vectors[q1][q2]<<endl;
}
return 0;
}
Can somebody explain me this code? Or if anyone has a better approach to solve this problem. Then please explain it in detail.
This shouldn't be hard to understand, that code is basically initializing dynamic 2D array at run time then inserting values to the 2D array and then accessing it by giving index:
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j]; // initialzing inner array.. consider it as 2D array with n rows and j columns
for (int y=0;y<j;y++)
cin>>Vectors[i][y]; // insert element at specified index
}
cout<<Vectors[q1][q2]<<endl; // access element from 2D array
What you might want to use is a Matrix class.
Using
vector<vector<int>>
should do it.
Alternatively the snipet code should be refactored into a Matrix class with a constructor and a destructor.
The example you give present a memory leak since the allocated memory is not freed.

Not getting the input values when printing vector of pairs

I want to add a pair to a vector of pairs.
When I print the vector elements, I don't get the integers I input.
Please help.
#include<iostream>
#include<vector>
#include<utility>
using namespace std;
int main()
{
vector<vector<unsigned long int> >matrix;
vector<pair<int,int> >pmat;
int L;
cin>>L;
int n1, n2;
pmat.resize(L);
for(int k = 0; k<L; k++)
{
cin>>n1>>n2;
pair<int,int> p = make_pair(n1,n2);
cout<<p.first<<p.second<<endl;
pmat.push_back(p);
}
for(int k = 0; k<L; k++)
{
cout<<pmat[k].first<<','<<pmat[k].second<<' ';
}
cout<<endl;
return 0;
}
Method 1:
Delete this line:
pmat.resize(L);
You don't need to resize it in the first place as you do push_back() when adding afterwards.
Method 2:
Change the following line
pmat.push_back(p);
to
pmat[k] = p;
You can do resize() in the first place, but after this, you should not use push_back() when adding, just use pmat[k] = p.
PS: you should not mix these two ways up. Always use one of them consistently.
Since you're using pmat.resize(L) and L times pmat.push_back(...), you're ending up having stored 2 * L entries in your vector. However you're printing just the first half, index 0 to L - 1. The values you want are stored from index L to 2 * L - 1.
Just change pmat.resize(L) to pmat.reserve(L).
Alternatively, you can use the resize(L), but to end up with L entries, you need to store each input pair to pmat[k], hence you write pmat[k] = p;.
As a rule of thumb, I recommend using the reserve + push_back approach if you know how many elements you're going to add. The reason is, that resize initializes the elements, while reserving just asserts that there will be enough space and no reallocation will be necessary with any following push_back.
You don't want to add more pairs after you allocated them. You can now directly access them.
Just use pmat[k] = p; instead of pmat.push_back(p);
If you print the size of the vector after reading the values, you will notice a small problem with your program:
./test
2
1 2
12
3 4
34
Size of the vector: 4
0,0 0,0
Huh? Even though I only entered 2 pairs, the size of the vector is 4. How did this happen?
If you look at the documentation for resize, it says
Resizes the container to contain count elements.
So even before you read any values, your vector will already contain 2 elements! Those will be default-constructed and therefore be 0. When you then push_pack the elements you read in, those will land at the indices 2 and 3 in the vector, so the end vector has twice as much elements as you wanted (4 in this case). You only print out the first half, which are the zero values.
The solution is to use reserve instead of resize, which doesn't create the elements but only reserves space for them, or just delete the call to resize. Using reserve is more efficient though, because then the vector will only need to allocate memory once.
pmat.resize(L);
if vector in empty its going to initialize a vector pmat with size L then assign default values to vector so now pmat size is L with default values
for(int k = 0; k<L; k++)
{
cin>>n1>>n2;
pair<int,int> p = make_pair(n1,n2);
cout<<p.first<<p.second<<endl;
pmat.push_back(p);
}
then u r pushing values to pmat L times so the final size is 2*L
for(int k = 0; k<L; k++)
{
cout<<pmat[k].first<<','<<pmat[k].second<<' ';
}
here u r going to read from 0 to L-1 , it contains default values you can see your values from L-1 to 2L-1.
so finally what i want say is use reserve instead of resize
or
pmat.resize(L); comment this line