getting segmented fault error in hackerrank problem- Variable Length Array [duplicate] - c++

This question already has answers here:
Segmentation fault on large array sizes
(7 answers)
Closed 1 year ago.
https://www.hackerrank.com/challenges/variable-sized-arrays/problem
This is the problem statement.
I tried the following code
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n,q;
cin>>n>>q;
int n1;
int A[n][1000000];
for(int i =0; i<n; i++)
{ cin>>n1;
for(int j=0; j<n1; j++){
int c;
cin>>c;
A[i][j] = c;
}
}
int a,b;
for(int i=0;i<q; i++){
cin>>a>>b;
cout<<A[a][b]<<"\n";
}
return 0;
}
This code passes the sample test case and other custom inputs(I have tried for small number of input values). But it does not work for Test cases in which the value of n and q (as mentioned in the problem) are large. It gives the "Segmented Fault" error. Can someone please explain why I am getting that error.

Over here int A[n][1000000]; your allocating a n * 1000000 number of elements. That is a huge number. If we consider an int to be 32 bits (or 4 bytes), your talking about n * 4000000 bytes worth of data, which will most probably will be in the range of Megabytes and hence your error. This is easily too much to be stack allocated, and greatly inefficient.
Consider using std::vector<> instead.

Related

Why is a variable I've scanned changing upon scanning a separate array? [duplicate]

This question already has answers here:
Why declaring the size of an array as n, before inputting n, works for the first time but not the second time?
(2 answers)
Why is "int arr[n];" causing my program to hang when the index "n" is to be inputted later by scanf()?
(4 answers)
why this code can't reverse an array properly
(3 answers)
Sum the positive elements of an array using recursion
(3 answers)
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
I'm going through the challenges for C++ on HackerRank and I've gotten stuck at the arrays introduction. It's giving me a sample input of
4
1 4 3 2
Where n=4 is the size of the array and the following line gives the array with n random integers. I ran into an issue with n=4 changing after my first for loop when answering the question, so I've been messing with it to try to understand it.
At the moment, I'm simply trying to scan the sample input numbers but n keeps changing once I've scanned the last element of the array:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n, arr[n];
scanf("%d", &n);
printf("%d \n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
printf("%d ", arr[i]);
printf("n=");
printf("%d ", n);
}
printf("\n%d", n);
return 0;
}
which gives me the following output:
4
1 n=4 4 n=4 3 n=4 2 n=2
2
Can anyone explain why n changes to a 2 after the final loop and stays as n=2 for all subsequent uses? How is it affected when I haven't assigned it to anything? This is the only sample input they give me as practice but they try a lot more with 1<=n<=1000 after I submit it and I want to understand it without cheating.
First in C++, the size of an array must be a compile-time constant.So, take for example the following code snippets:
int n = 10;
int arr[n]; //INCORRECT because n is not a constant expression
The correct way to write the above would be:
const int n = 10;
int arr[n]; //CORRECT
Similarly, the following(which you did in your code example) is incorrect:
int n, arr[n]; //INCORRECT, Note n has garbage value and using this garbage value leads
//to undefined behavior and also n is not a constant expression
Note the above statement has 2 problems:
First since you have not initialized n, it has an indeterminate value and you're using that value which is undefined behavior.
Second n is not a constant expression.
To solve this,you should use std::vector instead of using built in array as shown below:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
int n = 0;
std::cin >> n;
//create a vector of size n
std::vector<int> arr(n);
printf("%d \n", n);
//iterator through the vector
for (int &element: arr) {
std::cin >> element ;
std::cout<<element <<" ";
//add other code here
}
return 0;
}

C++ problem where the value assigned to a variable is getting changed even though it hasn't been modified yet [duplicate]

This question already has answers here:
Uninitialized variable behaviour in C++
(4 answers)
Closed 1 year ago.
Please help me with this strange problem where the input value is given as 4 (i.e. n = 4) and after a for loop the same value is getting displayed as 2, but why? It was not used anywhere (AFAIK) and it shouldn't get changed (I have no clue about it).
The original problem on HackerRank.
MY CODE >>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n;
int arr[n];
cin >> n; // input given from stdin is 4
cout << n << "\n"; // outputs 4
for(int i=0; i<n; i++){
scanf("%d",&arr[i]);
}
cout << n << "\n"; // outputs 2 (but why?)
for(int i=n-1; i>=0; i--){
printf("%d ",arr[i]); // if it were n = 4, then i will go from 3 to 0, but it goes from 1 to 0 (as n=2, but again, why?)
}
return 0;
}
Thank you for any help!
int n;
int arr[n]; // <<<<<< I magically know what n will be after the user types it!
cin >> n; // input given from stdin is 4
First of all, that's not even legal in C++. As a gcc extension to support C style VLA's, what is the value of n when the array declaration is seen? You have not read it yet!!
Instead, use:
int n;
cin >> n;
std::vector arr(n);
Although this still is not the "C++ way" as you are pre-defining the entire collection and then assigning to each element in turn; as opposed to adding each element to the collection. This is not a big deal with an int but more generally you don't want dead unused items in a collection; rather they simply don't exist at all.
std::vector arr; // don't pre-allocate any size
for(int i=0; i<n; i++){
int val;
scanf("%d",&val); //<<< uhhhhhh. you know about `cin` why this?
arr.push_back(val);
}

What's the problem here causing "Invalid memory reference (SIGSEGV)" when integers 10^8 and upwards are used as input? [duplicate]

This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 2 years ago.
I've used different values of n below and above 10^8. It works fine below it. But starts showing SIGSEGV once the input to n increases upto 10^8 or more. Why does this happen? My compiler is g++ 7.4.0
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
long long int n, k, c = 0;
cin >> n >> k;
long long int arr[n];
for(long long int i =1; i <=n ; i+=2){
arr[c] = i;
c++;
}
for(long long int j =2; j <=n ; j+=2){
arr[c] = j;
c++;
}
cout << arr[k-1];
return 0;
}
You're allocating a large array on the stack -- when it gets too large, the stack overflows and you get a SIGSEGV.

std::vector size does not update after reserve and fill [duplicate]

This question already has answers here:
std::vector::resize() vs. std::vector::reserve()
(5 answers)
Closed 6 years ago.
I need to fill a vector in with particular values. I find that the below code works, except in that a.size() fails to change from 0. Adding a resize call after I put in the elements takes almost twice as long. It seems there should be an O(1) way to update the size, since I don't need to change any elements. Is there? Should I just not bother?
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
int main()
{
int n = 1e9;
vector<float> a;
a.reserve(n);
for (int i=0; i<n; i++)
a[i] = i;
cout << a[2]; //successfully prints as 1
cout << a.size(); //confusingly prints as 0
}
Edit: this is not a duplicate, as the linked question does not address benchmarking. It simply asks the difference in reserve and resize, which I am not asking about. This code works, and fast, but has the ugly side effect of leaving size() "incorrect."
std::vector::reserve() is not for creating elements. To create elements, you can use std::vector::resize().
Try this:
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
int main()
{
int n = 1e9;
vector<float> a;
a.resize(n);
for (int i=0; i<n; i++)
a[i] = i;
cout << a[2];
cout << a.size();
}

Reversing an Array Results In SegFault

#include <iostream>
using namespace std;
/*
*
*/
int main() {
int k, in[k],reversea[k],i,m,n;
cin>>k;
for (i=0;i<k;i++){
cin>>in[i];
}
for (m=k-1;m>=0;m--){
for (n=0;n<k;n++){
in[m]=reversea[n];
}
}
for(i=0;i<k;i++){
cout<<reversea[i];
}
return 0;
}
I have no idea why it says segmentation fault even before i start debugging it. I compile another one on calculating the frequency of 1, 5, and 10 in an array of k numbers, and it says the same thing...
Here is the other one:
#include <iostream>
using namespace std;
int main() {
int k,i,m,n,count5,count1,count10;
int input[k];
cin>>k;
for (i=0;i<k;i++){
cin>>input[i];
}//input all the numbers
for(i=0;i<k;i++){
if (input[i]=1){
count1++;
}
if (input[i]=5){
count5++;
}
if (input[i]=10){
count10++;
}
}
cout<<count1<<"\n"<<count5<<"\n"<<count10<<"\n";
return 0;
}
Please help me. Thanks.
On this line
int k, in[k],reversea[k]
How are you supposed to initialize an array with k elements if k isn't initialized? The size of an array must be known at compile time not run time. If k isn't know until run time, use a std::vector
int k;
std::cin >> k;
std::vector<int> in(k);
std::vector<int> reversea(k);
Both your programs have two major faults.
You need to know the size of an array while creating it. In your code, k is still uninitialized and you are using this value as the size of your array. Instead, change it to
int k,i,m,n;
cin >> k;
int in[k];
int reversea[k];
While reversing the array, you should be filling reversea using values from in, and not the other way round. Also, you don't need 2 for loops, just use 1 for loop.
for (m=k-1; m>=0; m--){
reversea[m] = in[k-1-m];
}
In the second program, you again need to get the value of k before creating the array input[k].
You are testing for equality with a = instead of == . Change your code from
if (input[i]=1){
to
if (input[i] == 1) {