Below is beginning of my c++ program. It looks quite normal for me but when I run it I gets segmentation fault. This is what the debugger gives me:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004008d4 in main () at usu.cpp:12
12 cin >> n >> k;
But the errer isn't connected with this line of code becouse when I put "reutrn 1" before for loop programs ends normally. What could be wrong? I compiling my program using: g++ -ggdb3
#include <iostream>
#include <stdio.h>
#define MAX_N 1000000
#define MAX_K 1000000
#define MAX_IL_KROKOW 500000
using namespace std;
int main()
{
int n, k;
cin >> n >> k;
char klocki[MAX_N+1];
int Przes_C[MAX_IL_KROKOW];//podaje następne c po c znajdującym się na pozycji i
int Ktore_b[MAX_N];//na podstawie indeksu b w klockach zwraca indeks w tablicy Przes_b
int Przes_b[MAX_N];//zwraca indeks b w klockach na podstawie występowania b
int poprz_c = -1;
int ilosc_b = 0;
int klocki_len = 0;
for(int i=0;i<n;i++)
{
klocki[i] = getchar();
return 1;
if(klocki[i] == 'b')
{
Przes_b[ilosc_b] = i;
Ktore_b[i] = ilosc_b;
ilosc_b++;
}
if(poprz_c != -1 && klocki[i] == 'c')
Przes_C[poprz_c] = i;
if(klocki[i] == 'c')
poprz_c = i;
klocki_len++;
}
klocki[klocki_len] = '\0';
It's likely youur array allocation fails which leads to undefined behaviour when you try to write something to the arrays.
char klocki[MAX_N+1];
int Przes_C[MAX_IL_KROKOW];
int Ktore_b[MAX_N];
int Przes_b[MAX_N];
These are massive arrays. There's only a fixed size of stack allocated per process. Created dynamic arrays using new.
You could also define the array variables as global variables outside the main function. Depends on your program (length) whether that makes sense.
Related
This is my code for finding the longest collatz sequence between 1 and n. And obviously for t test cases. Here, I have also used memoization and thus malloced 'v'. But as the input to the function cycles(int x) goes beyond 4254, ie. 4255, there is something peculiar happening. The function is being input a number 6053452 instead of 4255. And due to this, the program segfaults, as we have only allocated space for 5000000 integers. What have I done wrong?
Note: The program works pleasantly till n = 4254! (not the factorial)
#include <iostream>
#include <cstdlib>
#define RANGE 5000000
using namespace std;
int *v = (int*)malloc(sizeof(int)*RANGE);
int cycles(int x){
int c = 1;
while(x!=1){
if(v[x]!=0){
c = c + v[x];
break;
}
if(x%2){
x = 3*x + 1;
}else{
x/=2;
}
c++;
}
v[x] = c;
return c;
}
void solve(int n){
int mx = 0;
int mx_cnt = 0;
int c;
for(int i=1;i<=n;i++){
c = cycles(i);
if(c >= mx_cnt){
mx = i;
mx_cnt = c;
}
}
cout << mx << endl;
}
int main(){
int t,n;
cin >> t;
while(t--){
cin >> n;
solve(n);
}
return 0;
}
The main problem that you observe is that you access v out of bounds. You also use the mallocd memory uninitialized which makes the program have another problem. Both results in undefined behavior.
int cycles(int x){
int c = 1;
while(x!=1){
if(v[x]!=0){ // <- x >= RANGE
c = c + v[x];
break;
}
// ...
To find problems like this I suggest using a vector instead and, at least when developing the program, use the vector::at() bounds checking member function.
std::vector<int> v(RANGE);
int cycles(int x){
int c = 1;
while(x!=1){
// The below use of `v.at(x)` may result in an exception like:
// what(): vector::_M_range_check:
// __n (which is 6053452) >= this->size() (which is 5000000)
if(v.at(x)!=0){
c = c + v[x];
break;
}
// ...
To catch the exception, you could rewrite main like this:
#include <exception>
int main() {
int t, n;
try {
std::cin >> t;
while(t--) {
cin >> n;
solve(n);
}
} catch(const std::exception& ex) {
std::cout << "Exception: " << ex.what() << '\n';
}
}
If you have a modern 64 bit computer, allocating a lot more shouldn't be a problem. I did this and it solved 4255 fine:
constexpr size_t RANGE = 6810137;
v points to a malloced array and malloc does no initialization. You have if(v[x]!=0) and c = c + v[x]; operating on an uninitialized variables. Embrace C++ and replace the malloced array with a std::vector. vector initializes its contents.
This might not be the only bug, just the most obvious.
Correction based on point raised by molbdnilo in the comments: I reached for too complicated a tool. int v[RANGE]; will allocate and zero-initialize the array. Since the array never changes size, a vector's dynamic array is unnecessary. Use std::array<int, RANGE> v; and you'll have a zero-initialized fixed-size array and still get useful functions like at for debugging.
I am writing a simple program of linear search on vscode on macOS.
The code is producing an error called segmentation fault only in vscode.
But the strange thing is that code is working perfectly fine on onlinegdb compiler and Xcode IDE.
I have the default c++ compiler installed on my Mac which came after installing Xcode.
#include<iostream>
using namespace std;
int linearSearch(int arr[], int n, int key){
int i = 0;
for(i = 0; i<n;i++)
{
if(arr[i] == key){
return i;
}
} return -1;
}
int main(){
int n = 0;
int arr[n];
int key = 0;
cout<<"Enter the length of the array"<<endl;
cin>>n;
cout<<"Enter the elements of the array"<<endl;
int i = 0;
for(i = 0; i<n;i++)
{
cin>>arr[i];
}
cout<<"Enter the element to search in array"<<endl;
cin>>key;
cout<<linearSearch(arr, n, key);
}[screenshot of the error in vscode][1]
[1]: https://i.stack.imgur.com/Bo3Nu.png
Segmentation fault isn't a vscode error, its a program error, it indicates that your program is accessing a memory adress that it hasn't reserved, thus the OS kills your program to save the system from wrong or bad memory accesses.
You first initialize n with 0 and then initialize the array arr with n ints. So it makes you an array with 0 ints. If you want to make this work, push the int arr[n] below the cin >> n. You will have to convert it first from a string to a int using stoi()
libraries:
#include <string>
#include <iostream>
code:
//Create the int to store the length of the array
int n = 0;
//A string, beacause cin returns a string
std::string s;
//Get the number
std::cout << "Length of array: ";
std::cin >> s;
//Convert the string to an int
n = stoi(s);
//Create the array
int arr[n];
So I am working on a problem at HackerEarth which requires me to store an integer array of size 10^9.
I am trying to store the array using vector but I get runtime error SIGABRT when I try to Submit my Solution.
Here is my code:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
unsigned int h, c, q;
cin >> h >> c >> q;
vector<unsigned int> minht(h + 1);
for (unsigned int i = 0; i <= h; i++)
minht[i] = 0;
unsigned int hc, st, et;
for (unsigned int i = 1; i <= c; i++)
{
cin >> hc >> st >> et;
for (unsigned int j = 1; j <= h; j++)
{
if (j >= st && j <= et)
{
if (hc > minht[j])
minht[j] = hc;
}
}
}
unsigned int hq, tq;
for (unsigned int i = 1; i <= q; i++)
{
cin >> hq >> tq;
if (hq > minht[tq])
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
The code works fine when value of h is not very large(10^9) but I get SIGABRT when value of h is very large.
Any Suggestions?
EDIT:
So I tried rewriting my entire code and my new code looks like this:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
unsigned int h,c,q,mh=0;
cin>>h>>c>>q;
vector<unsigned int> hc(c+1);
vector<unsigned int> st(c+1);
vector<unsigned int> et(c+1);
for(unsigned int i=1;i<=c;i++)
{
cin>>hc[i]>>st[i]>>et[i];
if(mh<hc[i])mh=hc[i];
}
unsigned int ht,ti;
for(unsigned int i=1;i<=q;i++)
{
int flag=0;int ct=0;
cin>>ht>>ti;
if(ht<=mh)
{
for(unsigned int j=1;j<=c;j++)
{
if(ti>=st[j] && ti<=et[j])
{
if(ht<=hc[j])
{
ct=1;break;
}
}
}
}
if(ct==0)cout<<"YES\n";
else cout<<"NO\n";
}
}
and the solution was now accepted.
What I did was redesign the algorithm so that instead of having to store 1 VERY LARGE array of 4 GB, I had to store 3 LARGE arrays, each of maximum 40 MB.
So the problem is now solved but I but I still don't think that problem was related to memory issues.
Because when I tried to create a int vector of size 10E8, just to test out the online compiler, I got a specific Memory Limit Exceeded Error. But when I changed the size to 10E9 I got SIGABRT again. So although the memory issue is there, SIGABRT is being caused by declaring an array of 10E9 size.
Any idea what could be causing this??
Also, I first created the program on my own compiler and then submitted it online. I can't debug the program on my setup since the program requires me to enter 10E7 data values before I encounter the error, so I thought that it would be easier to do it on HackerEarth.
I am a beginner to C++.
I am trying to read in input from the console, so I have the code below:
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
#define maxn 2006
int A[maxn][maxn];
int main() {
memset(A,0,sizeof(A));
int n = 0,m = 0;
cin >> n >> m;
for(int i = 0; i < n; ++i){
string str; cin >> str;
for(int j =0; j < m; ++j)
A[i][j] = str[j]-'0';
}
return 0;
}
A sample input looks like this
5 7
0101010
1000101
0101010
1010101
0101010
My program above works perfectly.
However, for learning purpose, I did nothing but move the declaration of 2D int array A into the main function, which looks like this:
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
#define maxn 2006
int main() {
int A[maxn][maxn];
memset(A,0,sizeof(A));
int n = 0,m = 0;
cin >> n >> m;
for(int i = 0; i < n; ++i){
string str; cin >> str;
for(int j =0; j < m; ++j)
A[i][j] = str[j]-'0';
}
return 0;
}
I rebuild it and run, I get segmentation fault 11.
Anyone know what's going on here? Why does the code break down after the subtle change?
Thanks!
Anyone know what's going on here?
Yes: stack overflow.
By moving the variable you made it a local (stack allocated) instead of global (allocated at startup in the BSS section of the binary).
The size of your variable is 16,096,144 bytes (2006 * 2006 * 4). And stack is usually limited, often to 8MB. On a UNIX system, after ulimit -s unlimited, your modified program may start working again.
#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) {