Can someone explain this output? (C++) - c++

Hello can someone please explain the output of the following C++ code espacially the numbers after the output of the first one 43211223334444
Here is the code:
void rek(int i) {
if (i > 0){
cout << i;
rek(i-1);
for (int k=0; k < i; k++)
cout << i; }
}
int main(){
rek(4);
return 0;
}
Here is the output:
the output is: 43211223334444

All the trouble comes from the fact that your output didn't introduce any separation in values cout << i; prints.
You actually getting the following at first:
4, 3, 2, 1
We got this out of these two statements:
// ...
cout<< i;
rek(i-1);
// ...
Where each call to the rek(i) prints its current i and then calls rek(i-1), which in turn before proceed through the function body has to print its i-1 and then call rek((i-1)-1)... And so on, until it hits the i < 0 case.
The remaining part is brought to you by the output of 1 one time, 2 two times, 3 three times, and 4 four times. All because of the for loop:
for (int k=0; k < i; k++) // print the value of i, i times
cout << i;
Thus, you essentially have the following:
4
3
2
1 // We hit base case on next rek() call, so no print out of there
1 // Here the for loop comes in
2 2
3 3 3
4 4 4 4
By the way, please note that the placement of brace(s) in your code is somewhat counterintuitive.

We can write the dynamic stack development down manually. Below I have pseudo code with an indentation of four per stack level. The commands are on the left, the resulting output, in that order, on the right. I have replaced i with the respective number to make even more transparent what's going on.
rek(4)
cout << 4; 4
rek(3)
cout << 3; 3
rek(2)
cout << 2; 2
rek(1)
cout << 1; 1
rek(0)
if(i>0) // fails, rek(0) returns
rek(1) continues
for (int k=0; k < 1; k++)
cout << 1; 1
rek(1) returns
rek(2) continues
for (int k=0; k < 2; k++)
cout << 2; 2
cout << 2; 2
rek(2) returns
rek(3) continues
for (int k=0; k < 3; k++)
cout << 3; 3
cout << 3; 3
cout << 3; 3
rek(3) returns
rek(4) continues
for (int k=0; k < 4; k++)
cout << 4; 4
cout << 4; 4
cout << 4; 4
cout << 4; 4
rek(4) returns
main() continues
return 0;

Lets break your output string: "43211223334444" into 2 parts:
Part 1: "4321"
This is the result of
cout << i;
rek(i-1);
You are printing i and recursively calling same function by passing the (i-1) as argument and function performs the operation till (i > 0).
This prints the numbers from 4 to 1, i.e. "4321"
Part 2 "1223334444"
This is the result of code section:
for (int k=0; k < i; k++)
cout << i;
This section gets called in reverse order from number 1 to 4.
This code section basically prints the number i, for the i times.
For i=1 it prints: 1
For i=2 it prints: 22
For i=3 it prints: 333
For i=4 it prints: 4444
That makes the string: "1223334444"
Hope this explains you the total output string: "43211223334444"

you are doing recursive function and then a for-loop
and you're function is going deep in the recursion and then the for loop is working from the deepest point of the recursion that's why you see this output

You start with going "down in the recursive tree", first you complete printing the numbers from i=4 to i=1 and therefore you print: 4321.
After that you go "up the recursive tree" and start printing from i=1 to i=4 using the loop you wrote, therefore the order is now for i=1 you print 1 and for i=2 you print 22 which result in printing 1223334444 at the end of the line.

Related

Why does the code throw illegal memory access error

I want to know why the error appears when the code just gets into the function '
sort'
I made some check points using standard output. So I know where the error occurs.
I use repl.it to build this code
...
/*return pivot function*/
int partition(...){
...
}
void sort(vector<int> array, int left, int right){\
/*********"sort start" string dose not appear in console***********/
cout << "sort start";
// one element in array
if(left == right);
// two elements in array
else if( left +1 == right){
if(array.at(0) > array.at(1)){
int temp;
swap(array.at(0),array.at(1),temp);
}
}
// more then 3 elements in array
else{
int p = partition(array,left,right);
sort(array,left,p-1);
sort(array,p+1,right);
}
}
int main() {
vector<int> array;
array.push_back(1);
array.push_back(2);
array.push_back(3);
array.push_back(4);
cout << "array is ";
for(int i = 0 ; i < array.size(); i++){
cout << array.at(i) << " ";
}
cout << endl;
sort(array,0,array.size()-1);/***************sort is here*************/
cout << "sorting..." << endl;
cout << "array is ";
for(int i = 0 ; i < array.size(); i++){
cout << array.at(i) << " ";
}
return 0;
}
When I run this code console output is
array is 4 3 2 2
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 18446744073709551615) >=
this->size() (which is 4)
exited, aborted
But what I expected is
array is 4 3 2 2
sorting...
sort start
array is 2 2 3 4
You are trying to access an element at index -1, which, when converted into 64-bit unsigned value, is 18446744073709551615. Live demo: https://wandbox.org/permlink/jAhJZS3ANjkDDOUr.
There are multiple problems with your code and, first of all, you don't show us the definition of your partition and swap. Moreover, your code does not match the provided output (1 2 3 4 vs 4 3 2 2 in the first line).
Anyway, one of the problems is that you don't check for cases where left is higher than right. That can easily happen. Consider that in the very first call of sort, partition returns 0 (pivot position). Then, you call:
sort(array, left, p - 1);
which turns into
sort(array, 0, -1);
That's where negative indexes can be generated.

Program only works with inclusion of (side effects free) cout statements?

So I've been working on problem 15 from the Project Euler's website , and my solution was working great up until I decided to remove the cout statements I was using for debugging while writing the code. My solution works by generating Pascal's Triangle in a 1D array and finding the element that corresponds to the number of paths in the NxN lattice specified by the user. Here is my program:
#include <iostream>
using namespace std;
//Returns sum of first n natural numbers
int sumOfNaturals(const int n)
{
int sum = 0;
for (int i = 0; i <= n; i++)
{
sum += i;
}
return sum;
}
void latticePascal(const int x, const int y, int &size)
{
int numRows = 0;
int sum = sumOfNaturals(x + y + 1);
numRows = x + y + 1;
//Create array of size (sum of first x + y + 1 natural numbers) to hold all elements in P's T
unsigned long long *pascalsTriangle = new unsigned long long[sum];
size = sum;
//Initialize all elements to 0
for (int i = 0; i < sum; i++)
{
pascalsTriangle[i] = 0;
}
//Initialize top of P's T to 1
pascalsTriangle[0] = 1;
cout << "row 1:\n" << "pascalsTriangle[0] = " << 1 << "\n\n"; // <--------------------------------------------------------------------------------
//Iterate once for each row of P's T that is going to be generated
for (int i = 1; i <= numRows; i++)
{
int counter = 0;
//Initialize end of current row of P's T to 1
pascalsTriangle[sumOfNaturals(i + 1) - 1] = 1;
cout << "row " << i + 1 << endl; // <--------------------------------------------------------------------------------------------------------
//Iterate once for each element of current row of P's T
for (int j = sumOfNaturals(i); j < sumOfNaturals(i + 1); j++)
{
//Current element of P's T is not one of the row's ending 1s
if (j != sumOfNaturals(i) && j != (sumOfNaturals(i + 1)) - 1)
{
pascalsTriangle[j] = pascalsTriangle[sumOfNaturals(i - 1) + counter] + pascalsTriangle[sumOfNaturals(i - 1) + counter + 1];
cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n'; // <--------------------------------------------------------
counter++;
}
//Current element of P's T is one of the row's ending 1s
else
{
pascalsTriangle[j] = 1;
cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n'; // <---------------------------------------------------------
}
}
cout << endl;
}
cout << "Number of SE paths in a " << x << "x" << y << " lattice: " << pascalsTriangle[sumOfNaturals(x + y) + (((sumOfNaturals(x + y + 1) - 1) - sumOfNaturals(x + y)) / 2)] << endl;
delete[] pascalsTriangle;
return;
}
int main()
{
int size = 0, dim1 = 0, dim2 = 0;
cout << "Enter dimension 1 for lattice grid: ";
cin >> dim1;
cout << "Enter dimension 2 for lattice grid: ";
cin >> dim2;
latticePascal(dim1, dim2, size);
return 0;
}
The cout statements that seem to be saving my program are marked with commented arrows. It seems to work as long as any of these lines are included. If all of these statements are removed, then the program will print: "Number of SE paths in a " and then hang for a couple of seconds before terminating without printing the answer. I want this program to be as clean as possible and to simply output the answer without having to print the entire contents of the triangle, so it is not working as intended in its current state.
There's a good chance that either the expression to calculate the array index or the one to calculate the array size for allocation causes undefined behaviour, for example, a stack overflow.
Because the visibility of this undefined behaviour to you is not defined the program can work as you intended or it can do something else - which could explain why it works with one compiler but not another.
You could use a vector with vector::resize() and vector::at() instead of an array with new and [] to get some improved information in the case that the program aborts before writing or flushing all of its output due to an invalid memory access.
If the problem is due to an invalid index being used then vector::at() will raise an exception which you won't catch and many debuggers will stop when they find this pair of factors together and they'll help you to inspect the point in the program where the problem occurred and key facts like which index you were trying to access and the contents of the variables.
They'll typically show you more "stack frames" than you expect but some are internal details of how the system manages uncaught exceptions and you should expect that the debugger helps you to find the stack frame relevant to your problem evolving so you can inspect the context of that one.
Your program works well with g++ on Linux:
$ g++ -o main pascal.cpp
$ ./main
Enter dimension 1 for lattice grid: 3
Enter dimension 2 for lattice grid: 4
Number of SE paths in a 3x4 lattice: 35
There's got to be something else since your cout statements have no side effects.
Here's an idea on how to debug this: open 2 visual studio instances, one will have the version without the cout statements, and the other one will have the version with them. Simply do a step by step debug to find the first difference between them. My guess is that you will realize that the cout statements have nothing to do with the error.

Why dοes this code output 1?

I'm trying to figure out this C++ code line by line.
Can anyone explain it for me? Why is the output 1?
int main() {
int sum = 0;
for (int i=0; i<10; i++)
if (sum%2==0)
sum += i;
else
continue;
cout << sum << endl;
}
The code can be roughly translated to the English:
Start with a sum of zero then, for every number from 0 to 9 inclusive, add it to the sum if and only if the current sum is even.
So, you'll add zero to the sum (because the sum is currently even) after which the sum will still be zero (hence even).
Then you'll add one to the sum (because the sum is currently even) after which the sum will be one (hence odd).
Then you'll never add anything to the sum again (because it's odd and will remain so because you're not adding anything to it).
That's why it outputs one.
You may find it more instructive to simply modify your program to output what it's "thinking". The following changes will hopefully make it easier to understand:
#include <iostream>
using namespace std;
int main(void) {
int sum = 0;
for (int i = 0; i < 10; i++) {
cout << "Processing " << i
<< ", sum is " << sum
<< ((sum % 2 == 0) ? " (even):" : " (odd): ");
if (sum % 2 == 0) {
sum += i;
cout << "adding " << i << " to get " << sum;
} else {
cout << "leaving at " << sum;
}
cout << '\n';
}
cout << "Final value is " << sum << '\n';
}
Running that code will show you the steps along the way:
Processing 0, sum is 0 (even): adding 0 to get 0
Processing 1, sum is 0 (even): adding 1 to get 1
Processing 2, sum is 1 (odd): leaving at 1
Processing 3, sum is 1 (odd): leaving at 1
Processing 4, sum is 1 (odd): leaving at 1
Processing 5, sum is 1 (odd): leaving at 1
Processing 6, sum is 1 (odd): leaving at 1
Processing 7, sum is 1 (odd): leaving at 1
Processing 8, sum is 1 (odd): leaving at 1
Processing 9, sum is 1 (odd): leaving at 1
Final value is 1
I created a table trying to simulate the debug steps for you to understand the logic of your code and see why the result is evaluated to 1
Recommendation: learn how to debug. Depending on the IDE you are using they approach code debugging differently. Debug come in handy when you want to understand how your code is being executed.
About your code:
Try to use curly braces when possible, this helps your code to be clean and more understandable;
else continue: you don't need this line of code because there's nothing to skip in your loop after else condition;
Exchanging the comparison from
if (sum%2==0)
to
if (i%2==0)
would make sense.
This would sum up the even numbers 0+2+4+6+8 -> 20.

MPI: Process 0 executing its code twice

I'm having a weird problem with an MPI program. Part of the code is supposed to be executed by the root (process zero) only, but process zero seems to execute it twice. For example,
root = 0;
if (rank == root) {
cout << "Hello from process " << rank << endl;
}
gives
Hello from process 0
Hello from process 0
This seems to only happen when I use 16 or more processes. I've been trying to debug this for quite a few days but couldn't.
Since I don't know why this is happening, I think I have to copy my entire code here. I made it nice and clear. The goal is to multiply two matrices (with simplifying assumptions). The problem happens in the final if block.
#include <iostream>
#include <cstdlib>
#include <cmath>
#include "mpi.h"
using namespace std;
int main(int argc, char *argv[]) {
if (argc != 2) {
cout << "Use one argument to specify the N of the matrices." << endl;
return -1;
}
int N = atoi(argv[1]);
int A[N][N], B[N][N], res[N][N];
int i, j, k, start, end, P, p, rank;
int root=0;
MPI::Status status;
MPI::Init(argc, argv);
rank = MPI::COMM_WORLD.Get_rank();
P = MPI::COMM_WORLD.Get_size();
p = sqrt(P);
/* Designate the start and end position for each process. */
start = rank * N/p;
end = (rank+1) * N/p;
if (rank == root) { // No problem here
/* Initialize matrices. */
for (i=0; i<N; i++)
for (j=0; j<N; j++) {
A[i][j] = N*i + j;
B[i][j] = N*i + j;
}
cout << endl << "Matrix A: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << A[i][j];
if(j==N-1)
cout << endl;
}
cout << endl << "Matrix B: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << B[i][j];
if(j==N-1)
cout << endl;
}
}
/* Broadcast B to all processes. */
MPI::COMM_WORLD.Bcast(B, N*N, MPI::INT, 0);
/* Scatter A to all processes. */
MPI::COMM_WORLD.Scatter(A, N*N/p, MPI::INT, A[start], N*N/p, MPI::INT, 0);
/* Compute your portion of the final result. */
for(i=start; i<end; i++)
for(j=0; j<N; j++) {
res[i][j] = 0;
for(k=0; k<N; k++)
res[i][j] += A[i][k]*B[k][j];
}
MPI::COMM_WORLD.Barrier();
/* Gather results form all processes. */
MPI::COMM_WORLD.Gather(res[start], N*N/p, MPI::INT, res, N*N/p, MPI::INT, 0);
if (rank == root) { // HERE is the problem!
// This chunk executes twice in process 0
cout << endl << "Result of A x B: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << res[i][j];
if(j == N-1)
cout << endl;
}
}
MPI::Finalize();
return 0;
}
When I run the program with P = 16 and two 4x4 matrices:
>$ mpirun -np 16 ./myprog 4
Matrix A:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Matrix B:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Result of A x B:
6366632 0 0 0
-12032 32767 0 0
0 0 -1431597088 10922
1 10922 0 0
Result of A x B:
56 62 68 74
152 174 196 218
248 286 324 362
344 398 452 506
Why is it printing out that first result?
I would really appreciate if someone was willing to help me.
You have undefined behavior / you are corrupting your memory. Let's assume your example with N=4,P=16,p=4. Therefore start=rank.
What do you do when you Scatter? You send 4 elements each to 16 processes. MPI will be assuming A on the root contains 64 elements, but it only contains 16. Further you store them at all ranks in A[start]. I don't even know if that is exactly defined, but it should be equal to A[start][0], which is out of the allocated memory for A when rank >= 4. So you already read and write to invalid memory. The wildly invalid memory accesses continue in the loop and Gather.
Unfortunately, MPI programs can be difficult to debug, especially with respect to memory corruption. There is very valuable info for OpenMPI. Read the entire page! mpirun -np 16 valgrind ... would have told you about the issue.
Some other notable issues:
The C++ bindings of MPI have been deprecated for years. You should
either use the C bindings in C++ or a high level binding such as
Boost.MPI.
Variable-length arrays are not standard C++.
You don't need a Barrier before the Gather.
Make sure your code is not full of unchecked assumptions. Do assert that P is square, if you need it to be, that N is divisible by p, if you need it to be.
Never name two variables P and p.
Now I am struggling as to what I should recommend you in addition to using debugging tools. If you need a fast parallel matrix multiplication - use a library. If you want to write nice high-level code as an exercise - use boost::mpi and some high-level matrix abstraction. If you want to write low-level code as an exercise - use std::vector<>(N*N), build your own 2D-index and think carefully how to index it and how to access the correct chunks of memory.

c++ vector not updating in nested for loop

So I create and initialize a vector (of size nmask+3) to 0, and I assign an initial value to one of the elements. I then make a for loop that goes through the first nmask elements of the vector and assigns to each element an average of 26 other elements in the vector (defined by the 4D int array voxt, which contains vector addresses).
My problem is that when I check the values of nonzero elements in my vector (phi) within the nested loop (the first cout), the values are fine and what I expect. However, when the loop finishes going through all nmask elements (for (int i= 0; i<nmask; i++) exits), I check the nonzero elements of phi again, and they are all lost (reset to 0) except for the last non-zero element (and element tvox which is manually set to 1).
I feel that since phi is initialized outside of all the loops, there should be no resetting of values going on, and that any updated elements within the nested loop should remain updated upon exit of the loop. Any ideas as to what is going on / how to fix this? Code is below; I tried to comment in a sense of the outputs I'm getting. Thanks in advance.
vector<double> phi(nmask+3, 0); //vector with nmask+3 elements all set to 0 (nmask = 13622)
phi[tvox]= 1; //tvox is predefined address (7666)
for (int n= 0; n<1; n++)
{
vector<double> tempPhi(phi); //copy phi to tempPhi
for (int i= 0; i<nmask; i++)
{
for (int a= -1; a<=1; a++)
{
for (int b= -1; b<=1; b++)
{
for (int c= -1; c<=1; c++)
{
if (!(a==0 && b==0 && c==0))
{
//oneD26 is just (double) 1/26
phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
if (phi[i]!=0)
{
//this gives expected results: 27 nonzero elements (including tvox)
cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl;
}
}
}
}
}
}
phi[svox]= 0; //svox = 7681
phi[tvox]= 1;
for (int q= 0; q<nmask; q++)
{
//this gives only 2 nonzero values: phi[tvox] and phi[9642], which was the last nonzero value from 1st cout
if (phi[q]!=0)
cout << q << " " << phi[q] << endl;
}
}
Difficult to tell just what is going on, but the easiest explanation is that after phi[i] gets set to non-zero and displayed to cout, it gets set to zero again in one of the later iterations through the inner loops.
If you do some tracing and check phi[i] just before updating you'll see that you often overwrite a non-zero element with zero.
Note: I have no idea what your code does, this is pure Sherlock Holmes reasoning.. if after the loops you find only 2 non-zero elements then the only logical consequence is that after updating something to non-zero later in the loop you update it to zero.
phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
The nested for-loops using a, b, and c run for a combined 9 iterations with the same value of i. Since you overwrite phi[i] to a new value every time, you only retain the value from the last iteration where a, and c are all 1. If that last iteration happens to produce zero values, then phi[i] will have lots of zeroes. Perhaps you meant to do something like phi[i] += ... instead of phi[i] = ...?
I do suggest to replace the meat of the loop with something like
const boost::irange domain(-1,2);
for (int i: boost::irange(0, nmask)) for (int a: domain) for (int b: domain) for (int c: domain)
{
if (a==0 && b==0 && c==0)
continue;
//oneD26 is just (double) 1/26
phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
if (phi[i]!=0)
{
//this gives expected results: 27 nonzero elements (including tvox)
cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl;
}
}
Of course, for brevity I assume both boost/range.hpp and c++0x compiler. However, with trivial macro's you can achieve the same. That is without writing/using a proper combinations algorithm (why is that not in the standard, anyway).