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.
Related
I was trying a test and I wrote this program...
#include<iostream>
using namespace std;
main()
{
int arr[5]={1,2,3,5,3}, num=5;
for(int i=0; i< num; i++)
{
for(int j=(i+1); i< num; j++)
{
if (arr[i]==arr[j])
{
cout<<"test";
}
cout<<j<<endl;
}
}
}
hmmm...
In the below code I know I used "i" instead of "j",So just to create the problem I used this
for(int j=(i+1); i< num; j++)
And my problematic part of the program is-
for(int j=(i+1); i< num; j++)
{
if (arr[i]==arr[j])
{
cout<<"test";
}
cout<<j<<endl;
}
in the above code when I remove this if block-
if (arr[i]==arr[j])
{
cout<<"test";
}
the program goes infinite.........
But when I put this if block again the program terminates automatically after some execution.
I also read about this on this link but it shows example of java
And there they show the reason of negative value, but in my program there is no garbage value comes.
The loop condition is never false. Hence the program will continue running indefinitely.
However, with if (arr[i]==arr[j]) you access outside the bounds of arr. Hence the behaviour of the program is undefined. When the behaviour of the program is undefined, it doesn't necessarily behave as you might expect. For example, it might not continue running indefinitely.
Even without if (arr[i]==arr[j]), the loop will eventually have undefined behaviour when the loop counter overflows. But a program with undefined behaviour doesn't necessarily behave as you might not expect. For example, it might continue running indefinitely.
Without the if (arr[i]==arr[j]), you simply have an infinite loop, which is perfectly valid in this case. j will just keep getting incremented (eventually this will overflow, which in undefined behaviour, see [basic.fundamental]/2), and the condition will never be met, since i does not change.
However, with the if (arr[i]==arr[j]) in the code, j is being incremented, and you will go outside the bounds of the array (as you know). In C++, this is Undefined Behaviour, meaning anything can happen. In your case, it seems to be causing the program to crash (which is actually a good thing, since it indicates an error).
I think, the problematic part of code is
for(int j=(i+1); i< num; j++)
You are increasing j while you are checking i< num.
If you replace it with
for(int j=(i+1); j < num; j++)
it might start working.
Why it is terminating with if block, and not terminating without if block
if (arr[i]==arr[j])
{
cout<<"test";
}
Because int have finite amount of possible values. When you reach the maximal value of int variable, the value + 1 is the smallest possible int. (As #user17732522 pointed out, the behavior might be utterly different - program crashing or something nasty happening here - because behavior of int 'overflowing' is undefined. Therefore your programs memory might be already corrupted here and it need to perform some operations to see it happened...eg. by program crash.)
Now, let's think about, what arr[i] does. arr is basically a pointer to a memory, where array begins and [i] operation is the same thing as *(arr + i).
Now, there are two possibilities what might happen
Program crashes when i is positive and outside of the array
Program crashes when i is negative
In both cases, the program crashes, because you are trying to access protected or nonexistent zone of a memory. This depends on the architecture of the system - Eg. In negative zone on 64 bit AMD64 system, you are clearly accessing nonexistent memory, if you don't have 16 exabytes of RAM. The program must in such case cause processor interruption, which is given to your OS, which kills your application.
Why it doesn't crashes when you delete the block? Nobody is trying to access the *(arr + j) and therefore, j is repeating from minimal possible value to maximal possible value without any problem.
The problem is this if statement will always be true:
for(int j=(i+1); i< num; j++){infinity}
Try setting it to this instead:
for(int j=(i+1); j< num; j++){not infinity}
You can't pass a loop on a statement that will not eventually return false or it'll go on forever.
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.
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 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...
This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 7 years ago.
While debugging I found an error with an int array of 0. In a test document I messed around with array with more cell input than their length.
int array[0];
for(int i = 0; i < 10; i++)
array[i] = i;
for(int i = 0; i < 10; i++)
cout << array[i];
After I compiled and ran the program I got
0123456789
Then I received the message "test.exe has stopped working". I expected both of these, but what I am confused about is why the compiler lets me create an array of 0, and why the program doesn't crash until the very end of the program. I expected the program to crash once I exceeded the array length.
Can someone explain?
The compiler should have at least warned you about a zero size array - if it didn't .. consider changing compiler.
Remember that an array is just a bit of memory just like any other. In your example the array is probably stored on the stack and so writing off the end of it may not cause much of a problem until your function exits. At that point you may find you have written some text over the return address and you get an exception. Writing off the end of arrays are a common cause of bugs in C/C++ - just be thankful you got an error with this one and it didn't just overwrite some other unrelated data.