why infinite loop terminates? or go infinite - c++

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.

Related

My C++ program gets slower as computation proceeds

I wrote a neural network program in C++ to test something, and I found that my program gets slower as computation proceeds. Since this kind of phenomenon is somewhat I've never seen before, I checked possible causes. Memory used by program did not change when it got slower. RAM and CPU status were fine when I ran the program.
Fortunately, the previous version of the program did not have such problem. So I finally found that a single statement that makes the program slow. The program does not get slower when I use this statement:
dw[k][i][j] = hidden[k-1][i].y * hidden[k][j].phi;
However, the program gets slower and slower as soon as I replace above statement with:
dw[k][i][j] = hidden[k-1][i].y * hidden[k][j].phi - lambda*w[k][i][j];
To solve this problem, I did my best to find and remove the cause but I failed... The below is the simple code structure. For the case that this is not the problem that is related to local statement, I uploaded my code to google drive. The URL is located at the end of this question.
MLP.h
class MLP
{
private:
...
double lambda;
double ***w;
double ***dw;
neuron **hidden;
...
MLP.cpp
...
for(k = n_depth - 1; k > 0; k--)
{
if(k == n_depth - 1)
...
else
{
...
for(j = 1; n_neuron > j; j++)
{
for(i = 0; n_neuron > i; i++)
{
//dw[k][i][j] = hidden[k-1][i].y * hidden[k][j].phi;
dw[k][i][j] = hidden[k-1][i].y * hidden[k][j].phi - lambda*w[k][i][j];
}
}
}
}
...
Full source code: https://drive.google.com/open?id=1A8Uw0hNDADp3-3VWAgO4eTtj4sVk_LZh
I'm not sure exactly why it gets slower and slower, but I do see where you can gain some performance.
Two and higher dimensional arrays are still stored in one dimensional
memory. This means (for C/C++ arrays) array[i][j] and array[i][j+1]
are adjacent to each other, whereas array[i][j] and array[i+1][j] may
be arbitrarily far apart.
Accessing data in a more-or-less sequential fashion, as stored in
physical memory, can dramatically speed up your code (sometimes by an
order of magnitude, or more)!
When modern CPUs load data from main memory into processor cache,
they fetch more than a single value. Instead they fetch a block of
memory containing the requested data and adjacent data (a cache line
). This means after array[i][j] is in the CPU cache, array[i][j+1] has
a good chance of already being in cache, whereas array[i+1][j] is
likely to still be in main memory.
Source: https://people.cs.clemson.edu/~dhouse/courses/405/papers/optimize.pdf
With your current code, w[k][i][j] will be read, and on the next iteration, w[k][i+1][j] will be read. You should invert i and j so that w is read in sequential order:
for(j = 1; n_neuron > j; ++j)
{
for(i = 0; n_neuron > i; ++i)
{
dw[k][j][i] = hidden[k-1][j].y * hidden[k][i].phi - lambda*w[k][j][i];
}
}
Also note that ++x should be slightly faster than x++, since x++ has to create a temporary containing the old value of x as the expression result. The compiler might optimize it when the value is unused though, but do not count on it.

c++ program shuts down in windows comparing a char to an array

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.

Vector unusual number when accessing out of range index

I the below code demonstrates strange behaviour when trying to access an out-of-range index in a vector
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a_vector(10, 0);
for(int i = 0; i < a_vector.size(); i++)
{
std::cout << a_vector[i] << ", ";
}
for(int j = 0; j <= a_vector.size(); j++)
{
std::cout << a_vector[i] << ", ";
}
return 0;
}
The first for loop produces the expected 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, output, however the second loop produces 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1318834149,.
The last number produced by the second loop changes every time to code is run, and is always large, unless the length of the vector is between three and seven (inclusive), in which case the last number is 0. It also persists for larger indexes - for example modifying the stop value of the second loop to j <= a_vector.size() + 2000 keeps producing large numbers until index 1139, at which point it reverts to 0.
Where does this number come from, does it mean anything, and most importantly why isn't the code throwing an 'out of range' error, which is what I would expect it to do when asked the access the 11th element of a vector 10 elements long
Did you meant ?
for(int j = 0; j < a_vector.size(); j++)
{
std::cout << a_vector[j] << ", ";
}
Because you're going out of the vector range, wich is an undefined behavior and will return and "random" number everytime your run it.
C++ is powerful, and with great power comes great responsibility. If you go out of range, it lets you. 99.99999999% of the time that isn't a good thing, but it still lets you do it.
As for why it changes every time, the computer is treating the hunk of memory after the end of the array as another int, then displaying it. The value of that int depends on what bits are left in that memory from when it was used last. It might have been used for a string allocated and discarded earlier in the program, it might be padding that the compiler inserts in memory allocations to optimize access, it might be active memory being used by another object. If you have no idea (like in this case), you have no way to know and shouldn't expect any sort of consistent behavior.
(What is the 0.00000001% when is it a good thing, you may ask? Once I intentionally reached beyond the range of an array in a subclass to access some private data in the parent class that had no accessor to fix a bug. This was in a library I had no control over, so I had to do this or live with the bug. Perhaps not exactly a good thing, but since I was confident of the layout of memory in that specific case it worked.)
ADDENDUM:
The case I mentioned was a pragmatic solution to a bad situation. Code needed to ship and the vendor wasn't going to fix a bug for months. Although I was confident of the behavior (I knew the exact target platform, the code was statically linked so wasn't going to be replaced by the user, etc.) this introduced code fragility and new responsibility for the future. Namely, the next time the library was updated it would almost certainly break.
So I commented the heck of the code explaining the exact issue, what I was doing, and when it should be removed. I also used lots of CAPITAL LETTERS in my commit message. And I told all of the other programmers, just in case I got hit by a bus before the bug was fixed. In other words, I exercised the great responsibility needed to wield this great power.

A segmentation fault

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...

for loop optimization c ++

this is my first time posting in this site and I hope I get some help/hint. I have an assignment where I need to optimize the performance to the inner for loop but I have no idea how to do that. the code was given in the assignment. I need to count the time(which I was able to do) and improve the performance.
Here is the code:
//header files
#define N_TIMES 200 //This is originally 200000 but changed it to test the program faster
#define ARRAY_SIZE 9973
int main (void) {
int *array = (int*)calloc(ARRAY_SIZE, sizeof(int));
int sum = 0;
int checksum = 0;
int i;
int j;
int x;
// Initialize the array with random values 0 to 13.
srand(time(NULL));
for (j=0; j < ARRAY_SIZE; j++) {
x = rand() / (int)(((unsigned)RAND_MAX + 1) / 14);
array[j] = x;
checksum += x;
}
//printf("Checksum is %d.\n",checksum);
for (i = 0; i < N_TIMES; i++) {
// Do not alter anything above this line.
// Need to optimize this for loop----------------------------------------
for (j=0; j < ARRAY_SIZE; j++) {
sum += array[j];
printf("Sum is now: %d\n",sum);
}
// Do not alter anything below this line.
// ---------------------------------------------------------------
// Check each iteration.
//
if (sum != checksum) {
printf("Checksum error!\n");
}
sum = 0;
}
return 0;
}
The code takes about 695 seconds to run. Any help on how to optimize it please?
thanks a lot.
The bottleneck in that loop is obviously the IO done by printf; since you are probably writing the output on a console, the output is line buffered, which means that the stdio buffer is flushed at each iteration, which slows down things a lot.
If you have to do all that prints, you can greatly enhance the performance by forcing the stream to do block buffering: before the for add a
setvbuf(stdout, NULL, _IOFBF, 0);
In alternative, if this approach is not considered valid, you can do your own buffering by allocating a big buffer on your own and do your own buffering: write in your buffer using sprintf, periodically emptying it in the output stream with a fwrite.
Also, you can use the poor man's approach to buffering - just use a buffer big enough to write all that stuff (you can calculate how big it must be quite easily) and write in it without worrying about when it's full, when to empty it, ... - just empty it at the end of the loop. edit: see #paxdiablo's answer for an example of this
Applying just the first optimization, what I get with time is
real 0m6.580s
user 0m0.236s
sys 0m2.400s
vs the original
real 0m8.451s
user 0m0.700s
sys 0m3.156s
So, we got down of ~3 seconds in real time, half a second in user time and ~0.7 seconds in system time. But what we can see here is the huge difference between user+sys and real, which means that the time is not spent in doing something inside the process, but waiting.
Thus, the real bottleneck here is not in our process, but in the process of the virtual terminal emulator: sending huge quantities of text to the console is going to be slow no matter what optimizations we do in our program; in other words, your task is not CPU-bound, but IO-bound, so CPU-targeted optimizations won't be of much benefit, since at the end you have to wait anyway for your IO device to do his slow stuff.
The real way to speed up such a program would be much simpler: avoid the slow IO device (the console) and just write the data to file (which, by the way, is block-buffered by default).
matteo#teokubuntu:~/cpp/test$ time ./a.out > test
real 0m0.369s
user 0m0.240s
sys 0m0.068s
Since there's absolutely no variation in that loop based on i (the outer loop), you don't need to calculate it each time.
In addition, the printing of the data should be outside the inner loop so as not to impose I/O costs on the calculation.
With those two things in mind, one possibility is:
static int sumCalculated = 0;
if (!sumCalculated) {
for (j=0; j < ARRAY_SIZE; j++) {
sum += array[j];
}
sumCalculated = 1;
}
printf("Sum is now: %d\n",sum);
although that has different output to the original which may be an issue (one line at the end rather than one line per addition).
If you do need to print the accumulating sum within the loop, I'd simply buffer that as well (since it doesn't vary each time through the i loop.
The string Sum is now: 999999999999\n (12 digits, it may vary depending on your int size) takes up 25 bytes (excluding terminating NUL). Multiply that by 9973 and you need a buffer of about 250K (including a terminating NUL). So something like this:
static char buff[250000];
static int sumCalculated = 0;
if (!sumCalculated) {
int offset = 0;
for (j=0; j < ARRAY_SIZE; j++) {
sum += array[j];
offset += sprintf (buff[offset], "Sum is now: %d\n",sum);
}
sumCalculated = 1;
}
printf ("%s", buff);
Now that sort of defeats the whole intent of the outer loop as a benchmark tool but loop-invariant removal is a valid approach to optimisation.
Move the printf outside the for loop.
// Do not alter anything above this line.
//Need to optimize this for loop----------------------------------------
for (j=0; j < ARRAY_SIZE; j++) {
sum += array[j];
}
printf("Sum is now: %d\n",sum);
// Do not alter anything below this line.
// ---------------------------------------------------------------
Getting the I/O out of the loop is a big help.
Depending on the compiler and machine, you might get a tiny increase in speed by using pointers rather than indexing (though on modern hardware, it generally doesn't make a difference).
Loop unrolling might help to increase the ratio of useful work to loop overhead.
You could use vector instructions (e.g., SIMD) to do a bunch of calculation in parallel.
Are you allowed to pack the array? Can you use an array of a smaller type than int (given that all the values are very small)? Making the array physically shorter improves locality.
Loop unrolling might look something like this:
for (int j = 0; j < ARRAY_SIZE; j += 2) {
sum += array[j] + array[j+1];
}
You'd have to figure out what to do if the array isn't an exact multiple of the unrolling size (which is probably why the assignment uses a prime number).
You would have to experiment to see how much unrolling would be the right amount.