The following program gives the correct output but gives segmentation fault(core dumped in the end)
#include <iostream>
using namespace std;
int main()
{
int a[50],n,i,c[50],b[50];
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=100;i++)
b[i]=0;
for(i=1;i<=n;i++)
{
b[a[i]]++;
}
for(i=2;i<=100;i++)
{
b[i]=b[i]+b[i-1];
}
for(i=1;i<=n;i++)
{
c[b[a[i]]]=a[i];
b[a[i]]--;
}
for(i=1;i<=n;i++)
cout<<c[i]<<endl;
return 0;
}
Here is the debugger output
gdb
Apart from other conditions in your program, at least this loop causes a buffer overflow and hence invokes undefined behavior!
for(i=1;i<=100;i++)
b[i]=0;
That is, because b has only 50 elements, and you're accessing memory waaay beyond that range. Also C arrays a zero-index based.
Note, that you likely cause UB in other statements as well, but this one was the first I noticed skimming over your code.
You are going out of bounds here:
for(i=2;i<=100;i++)
{
b[i]=b[i]+b[i-1];
}
since b is an array of size 50 and you allow i to reach the value of 100 and index the array. This causes the segmentation fault.
PS: Other loops may also index your arrays out of bounds, depending on the input you receive, since you don't check the input.
Related
I tryed to run the following code in my cygwin
#include<iostream>
#include<cstdio>
using namespace std;
const int NR=2005;
int n,m;
bool arr[NR][NR];
int mx_jx(int x){
int up[NR][NR],lf[NR][NR],rt[NR][NR];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
up[i][j]=1,lf[i][j]=rt[i][j]=j;
for(int i=1;i<=n;i++)
for(int j=2;j<=m;j++)
if(arr[i][j-1]==x)lf[i][j]=lf[i][j-1];
for(int i=1;i<=n;i++)
for(int j=m-1;j>=1;j--)
if(arr[i][j+1]==x)rt[i][j]=rt[i][j+1];
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(arr[i][j]!=x)continue;
if(i>1 && arr[i-1][j]==x){
up[i][j]=arr[i][j-1]+1;
lf[i][j]=max(lf[i][j],lf[i-1][j]);
rt[i][j]=min(rt[i][j],rt[i-1][j]);
}
ans=max(ans,(rt[i][j]-lf[i][j]+1)*up[i][j]);
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
int tmp;
scanf("%d",&tmp);
arr[i][j]=(int)tmp;
if((i+j)&1)arr[i][j]=!arr[i][j];
}
printf("%d",max(mx_jx(0),mx_jx(1)));
return 0;
}
It passed the compile(0 warning,0 error), but when I tried to run it with the following input
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
It says "Command terminated"
these code could run correctly on other platform, how can I solve this problem on cygwin? thanks a lot
While the answer from user3684240 is valid and it is definitely an issue with your code, more likely you have Stack Overflow due to allocating numerous huge arrays on stack and in global memory area.
You should use std::vector<std::vector<int> instead of plain C arrays.
std::vector<std::vector<int>> up(NR, std::vector<int>(NR, 0));
std::vector<std::vector<int>> lf(NR, std::vector<int>(NR, 0));
std::vector<std::vector<int>> rt(NR, std::vector<int>(NR, 0));
It is not very well optimized, but it's simplest solution I can provide.
For that bool array though, std::vector might behave... strange. I cannot give 100% guarantee that it will work if you simply substitute bool[][] with std::vector<std::vector<bool>> without testing it properly, because std::vector<bool> is optimized for memory and it has certain quirks that one should be aware of when using it.
You can try and see if that array of bools in global memory works (after changing arrays in mx_jx to vectors), maybe it does and you don't have to change it. If it doesn't, you can try to change to vector of vectors, then it should work.
The mistake is in that line:
scanf("%d", &arr[i][j]);
%d reads ints, but your array is of type bool. This leads to a memory error.
An easy way to fix it would be:
int read_value;
scanf("%d", &read_value);
arr[i][j] = read_value;
As an additional hint: If you enable compiler warnings (-Wall -Wextra -pedantic), the compiler will tell you about those kinds of mistakes.
I get a strange behavior when running a test code for MPI_Scatter. The program seems to work fine, but it returns a segmentation fault if the number of nodes is larger than 4. I compile with mpicxx and run with mpirun -n N ./a.o.
#include <mpi.h>
#include <vector>
#include <stdio.h>
using std::vector;
int main(void){
MPI_Init(NULL,NULL);
int num_PE;
MPI_Comm_size(MPI_COMM_WORLD, &num_PE);
int my_PE;
MPI_Comm_rank(MPI_COMM_WORLD, &my_PE);
int data_per_PE=2;
int remainder=0; //conceptually should be less than data_per_PE but shouldn't matter from code perspective
vector<int> elem_count(num_PE,data_per_PE); //number of elements to scatter
elem_count[num_PE-1]=data_per_PE+remainder; //let last PE take extra load
vector<int> start_send(num_PE); //the offset to send from main buffer
vector<double> small_vec(data_per_PE+remainder); //small place to store values
vector<double> bigVec; //the big list to distribute to processes
if (my_PE==0){
bigVec.reserve(data_per_PE*num_PE+remainder); //make room
for(int i=0; i<data_per_PE*num_PE+remainder; i++){
bigVec.push_back(static_cast<double>(i)+1.0); //1,2,3...
start_send[i]=i*data_per_PE; //the stride
}
}
// MPI_Scatterv(&bigVec[0],&elem_count[0],&start_send[0],MPI_DOUBLE,&small_vec[0],data_per_PE+remainder,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Scatter(&bigVec[0],data_per_PE,MPI_DOUBLE,&small_vec[0],data_per_PE,MPI_DOUBLE,0,MPI_COMM_WORLD); //scatter
if (my_PE==0){
printf("Proc \t elems \n");
}
MPI_Barrier(MPI_COMM_WORLD); //let everything catch up before printing
for (int i=0;i<data_per_PE+remainder;i++){
printf("%d \t %f \n", my_PE, small_vec[i]); //print the values scattered to each processor
}
MPI_Barrier(MPI_COMM_WORLD); //don't think this is necessary but won't hurt
MPI_Finalize(); //finish
return 0;
}
The issue has nothing to do with the scatter, but rather this line:
start_send[i]=i*data_per_PE;
Since i can go beyond num_PE, you write outside of the bounds of start_send - overwriting some memory that probably belongs to small_vec.
This could have easily been found by creating a truly minimal example.
You have another issue in your code: &bigVec[0] is a problem for my_PE!=0. While the parameter to MPI_Scatter is ignored by non-root ranks, the statement involves dereferencing in std::vector::operator[] the first element. As the vector is empty, this is undefined behavior on it's own. Here is an explanation as to why that can create subtle problems. Use bigVec.data() instead.
You are writing past the end of start_send's internal storage, thus corrupting the heap and any other objects contained in it:
if (my_PE==0){
bigVec.reserve(data_per_PE*num_PE+remainder); //make room
for(int i=0; i<data_per_PE*num_PE+remainder; i++){
bigVec.push_back(static_cast<double>(i)+1.0); //1,2,3...
start_send[i]=i*data_per_PE; //the stride <--- HERE
}
}
i runs until data_per_PE*num_PE+remainder - 1, but start_send has storage for num_PE elements only. Writing past the end corrupts the linked list of heap objects and the program likely segfaults when a destructor tries to free a corrupted heap block or when some other heap object is accessed.
This question already has an answer here:
will Index Out Of Array Bounds throw exception or error before core in C++?
(1 answer)
Closed 5 years ago.
I have this code:
#include <cstdio>
int foo[100];
int main()
{
for(int i=0;i<10000;i++)
foo[i]=10000;
}
Debugging with GDB gives a surprising result:
[New Thread 23684.0x59b4]
[New Thread 23684.0x5c0c]
[New Thread 23684.0x541c]
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401564 in main () at C:\Users\DARREN\Documents\Visual Studio
2017\Projects\Untitled1.cpp:9
warning: Source file is more recent than executable.
9 }
(gdb) print i
$1 = 4080
(gdb)
Now, I know the statement foo[i]=10000 caused the error, but I declared foo to be only of size 100. Why would the value of i be so big before the error occurs?
Any explanation is appreciated.
After you made an update to your question you posted this:
int foo[100];
int main()
{
for(int i=0;i<10000;i++)
foo[i]=10000;
}
And you are asking about segmentation fault.
Here you have an array with a size of 100 and you have a loop that ranges [0,9999] and within the for loop you are indexing the array with the for loops incremental variable i. When you step through the for loop for each iteration of i and you get to:
foo[i] = 10000;
when i <= 99 everything is okay.
What do you suppose happens when i >= 100?
When you use raw arrays there is no bounds checking; and this is something that you and the user will have to be responsible for. If you want automatic bounds checking done for you to prevent this out of bounds memory segmentation fault you should use any of the standard containers such as std::vector<T>, std::list<T>, std::set<T> etc. depending on your needs. If you need to use array index notation then std::vector<T> is the way to go. Or any other vector from any other library such as boost.
EDIT
For you to fix this problem you would have to either increase the size of the array from 100 to 10,000 or you would have to decrease your loop's condition from i<10000 to i<100 to accommodate for proper array indexing. Do not forget that C++ arrays have their starting index at 0 so you would have a basic array and loop as such:
int var[10]; // Uninitialized
for ( int i = 0; i < 10; ++i ) {
var[i] = 0; // Initialize all array indexes to 0
}
Notice that the condition in the for loop is i < 10 which is less than the actual size of the array when it is declared and not i <= 10 less than or equal to for this would also generate a segmentation fault or out of bounds error.
I have this part in the program
char size_input[5]={'1','0','4','-'};
for (int i=0;i<6;i++){
cin >> size_input[i];
if(size_input[i]!=char(45)){
valid_size_characters++;
}else{
i=6;
}
}
It compiles with no error in both windows and linux but in windows when the program reaches that part it just crashes and I have no idea why
It's an off-by-one error because your array has a size of 5 while the loop runs 6 times resulting in writing out of the array bounds causing undefined behavior. So it should be i<5 instead of i<6.
Also avoid exiting the loop by manipulating the loop index i, instead you could use break.
I have try the following code to judge prime:
const int N = 200000;
long prime[N] = {0};
long num_prime = 0;
int is_not_prime[N]={1,1};
void Prime_sort(void)
{
for( long i = 2 ; i<N ; i++ )
{
if( !is_not_prime[i] )
{
prime[num_prime++] = i;
}
for( long j = 0; j<num_prime && i*prime[i]<N ; j++ )
{
is_not_prime[i*prime[j]] = 1;
}
}
}
But when I run it, it cause a segmentation fault! That fault I have never meet.And I searched Google,and it explain segmentation fault as follow:
A segmentation fault (often shortened to segfault) is a particular
error condition that can occur during the operation of computer
software. In short, a segmentation fault occurs when a program
attempts to access a memory location that it is not allowed to access,
or attempts to access a memory location in a way that is not allowed
But I don't know where cause this fault in my code.Please help me.
Your array is_not_prime has length N. For example, at the final lap of the outer for loop, i will have the value N-1. When i is that big, is_not_prime[i*prime[j]] will cause you to write far out of bounds of the array.
I'm not quite sure what j<num_prime && i*prime[i]<N is supposed to do, but it is likely part of the bug. Single step through the program with your debugger and see at what values the variables have when the program crashes.
Just re-write your program in a less complex manner and all bugs will go away.
Compare your loop bound checking to your indexing - they aren't the same. (I believe you meant to write i*prime[j]<N in your for loop.)
Your program crashes because an index goes out of bounds. And the index goes out of bounds because your algorithm is not valid.
As it still crashes if you set N at a much smaller value
const int N = 3;
it shouln't be too difficult to see what goes wrong by running your program with pencil and paper...