-2

Hello dear Community,

I discovered weird behaviour when using std::cout. At line 75 I invoke the function "traverse(...)". traverse(...) will invoke "visit(int)". visit(int) will just print the int-parameter that is applied to the function.

I created a breakpoint on line 75 to investigate how the preorder on an binary-tree is working and discovered weird behaviour when it comes to the console-output of visit(int).

If I'm using at line 101, within the visit(int)-function:

std::cout << std::endl << "Node: " << i << std::endl;

It's normally printed. But if I will use:

std::cout << std::endl << "Node: " << i;

The zero (0) will not be printed if the visit(int)-function is executed first. Whilst examining the the debugger I observed the variable i that is applied to visit(i). From the beginning: i = 0, NO console output is printed, then the second run of visit(i) is executed with i = 2. But instead printing the 2, the 0 will be printed.

It seems that the missing

<< std::endl

will lead to weird behavior of the whole line.

Does anybody expected same issues? Just try it.

/* 
 * Project: Traversing of a binary-tree with the preorder (recursive).
 * Author: https://github.com/OtenMoten
 * 
 * A binary-tree is suitable for managing efficient data. 
 * "Preorder" means the algorithm will first check the root, then 
 * the left sub-tree and finally the right sub-tree.
 * 
 * Just check out https://stackoverflow.com/questions/2130416/what-are-the-applications-of-binary-trees
 * to read about the use-cases of binary-trees.
 * 
 * Coding Standard:
 * "a" = address variable (i.e. int& aTest;)
 * "i" = normal variable (i.e. int iTest;)
 * "p" = pointer variable (i.e. int* pTest;)
 * "x" = array (i.e. int xTest[10][5];)
 * 
 * Created on 6. Februar 2019, 23:05
 */

#include <cstdlib>
#include <stdio.h>
#include <iostream>

using namespace std;

constexpr int MAX_COLUMNS(4);

void print(int, int[][MAX_COLUMNS]);
void visit(int);
void height(int, int[][MAX_COLUMNS], int&, int&);
void traverse(int, int[][MAX_COLUMNS], int[]);
void out(int[]);

int main(int argc, char** argv) {

    constexpr int iCoutRows_Alpha = 9;
    constexpr int iCoutRows_Beta = 11;

    int aCurrentHeight = 0;
    int aFinalHeight = 1;
    int xDataFromTree[100] = {0};

    // Father - Left Son - Right Son - Data
    int xTreeAlpha[iCoutRows_Alpha][MAX_COLUMNS] = {
        {0, 5, 3, 0}, // Node 0 
        {4, 0, 0, 101}, // Node 1 
        {7, 0, 0, 102}, // Node 2 
        {0, 0, 0, 103}, // Node 3 
        {5, 1, 7, 0}, // Node 4 
        {0, 6, 4, 0}, // Node 5 
        {5, 0, 0, 104}, // Node 6 
        {4, 8, 2, 0}, // Node 7 
        {7, 0, 0, 105} // Node 8 
    };

    int xTreeBeta[iCoutRows_Beta][MAX_COLUMNS] = {
        {0, 2, 1, 0}, // Node 0 
        {0, 4, 8, 0}, // Node 1 
        {0, 5, 3, 0}, // Node 2 
        {2, 9, 6, 0}, // Node 3 
        {1, 10, 7, 0}, // Node 4 
        {2, 0, 0, 107}, // Node 5 
        {3, 0, 0, 102}, // Node 6 
        {4, 0, 0, 104}, // Node 7 
        {1, 0, 0, 101}, // Node 8 
        {3, 0, 0, 105}, // Node 9 
        {4, 0, 0, 103} // Node 10 
    };
    std::cout << std::endl;
    std::cout << "Preorder-Traversing" << std::endl;
    print(iCoutRows_Beta, xTreeBeta);
    std::cout << std::endl;

    traverse(0, xTreeBeta, xDataFromTree); // Start with the root, node 0.
    std::cout << std::endl << std::endl;

    height(0, xTreeBeta, aCurrentHeight, aFinalHeight);
    std::cout << "Height of the binary-tree = " << aFinalHeight;
    out(xDataFromTree);

    return 0;
};

void print(int iCountRows, int b[][MAX_COLUMNS]) {
    int iColumnA = 0;
    int iColumnB = 1;
    int iColumnC = 2;
    int iColumnD = 3;

    std::cout << std::endl;
    std::cout << "Binary-tree:";
    for (int iii = 0; iii < iCountRows; iii++) {
        std::cout << std::endl;
        std::cout << "Father - Left - Right - Data";
        printf("\n%3d %7d %7d %7d ", b[iii][iColumnA], b[iii][iColumnB], b[iii][iColumnC], b[iii][iColumnD]);
    };
};

void visit(int i) {
    std::cout << std::endl << "Node: " << i << std::endl;
};

void height(int root, int xBinaryTree[][4], int &aCurrentHeight, int &aFinalHeight) {
    aCurrentHeight++; // "aCurrentHeight" is the current layer of the node.
    if (aCurrentHeight > aFinalHeight) aFinalHeight = aCurrentHeight; // The final height is >= the current height.
    if (xBinaryTree[root][1] != 0) // The current node is NOT a leaf!
    {
        height(xBinaryTree[root][1], xBinaryTree, aCurrentHeight, aFinalHeight); // Get the height of the left sub-tree.
        height(xBinaryTree[root][2], xBinaryTree, aCurrentHeight, aFinalHeight); // Get the height of the right sub-tree.
    };
    aCurrentHeight--;
};

void traverse(int i, int baum[][4], int inhalt[]) {
    int az;
    visit(i);
    if (baum[i][1] != 0) // aktueller Knoten ist kein Blatt
    {
        traverse(baum[i][1], baum, inhalt); //linken Sohn
        traverse(baum[i][2], baum, inhalt); //rechten Sohn
    } else {
        az = inhalt[0]; // aktueller Knoten ist Blatt
        inhalt[az + 1] = baum[i][3];
        inhalt[0] = az + 1;
    };
};

void out(int xInputArray[]) {
    std::cout << std::endl;
    std::cout << "Count of leafs with data = " << xInputArray[0];
    std::cout << std::endl << std::endl;
    std::cout << "Data is:";

    for (int i = 1; i < xInputArray[0] + 1; i++) {
        std::cout << std::endl;
        std::cout << xInputArray[i];
    };
};

Kind regards Oten

Kevin O.
  • 355
  • 3
  • 11
  • Can you try to reproduce the issue you're talking about in fewer than 140 lines? If the issue is just about how something is printed, none of the logic around trees or traversal or anything is relevant. See [mcve], emphasis on minimal. – Barry Feb 07 '19 at 20:57
  • Read about what [`std::endl`](https://en.cppreference.com/w/cpp/io/manip/endl) does. And even then, use `'\n'` [instead of all those flushes](https://stackoverflow.com/questions/213907/c-stdendl-vs-n). – Pete Becker Feb 07 '19 at 20:57

1 Answers1

0

The std::cout object is buffered, which means its content is not flushed to the underlying device on each formatted output. std::endl flushes the object after it also appends a newline. Try adding this line after you are printing i:

std::cout.flush();

And see if it prints i.

erenon
  • 18,838
  • 2
  • 61
  • 93