-1

I have been trying to see why printf does not break the loop after printing the input of the file. The .c file is BST and I am now in the middle of testing whether a tree has been built but can't seem to exit the printf loop. I need the printf loop for the correct output for the code. Any suggestions of why this error is happening. Full code and output is shown.

#include "bst.h"
#include <stdio.h>
#include <stdlib.h>


///Author: Joe W

//arbitrary list of temp nodes

TreeNode *new_node, *root, *tmp, *parent;
int elemArray[100], i1, i2, i0;

/*
Insert a new node into the tree by referencing the root and using recursion
*/

    TreeNode* getN(int dataElem) {
        TreeNode* temp;
        temp = malloc(sizeof(TreeNode*));
        temp-> left = NULL;
        temp-> right = NULL;
        temp->data =  dataElem;
        return temp;
    } 



TreeNode* addNodeToTree(TreeNode *root, int data) {
    TreeNode* newNode = malloc(sizeof(TreeNode*));
    if (root == NULL)
    {

                                            // thingy too. Creating a function too,
                                            // for you to look at.
        root = newNode;
        return root;
    }
    else
    {
        TreeNode* parent = malloc(sizeof(TreeNode*));
        TreeNode* current = malloc(sizeof(TreeNode*));
        parent = current = root;
        // This loop will actually help us, find the `parent`, 
        // of the `newNode`(which is to be inserted)
        while (current != NULL)
        {
            parent = current;
            if (current->data > data)
                current = current->left;
            else if (current->data < data)
                current = current->right;
        }
        // Now once, we have found, the node, under which the
        // newNode will be placed, now we have to check, whether
        // newNode will become a `left child/right child` of the 
        // parent.
        newNode = getN(data);
        if (parent->data > data)
            parent->left = newNode;
        else if (parent->data < data)
            parent->right = newNode;


        return root;
    }
}


void build_Tree(TreeNode** root, const int elements[], const int count) {

    //TreeNode* node = malloc(sizeof(TreeNode*));
    //node->left = node ->right = NULL;



    for ( i0 = 0; i0 < count; ++i0 ){
        *root = addNodeToTree(*root, elements[count]);
    }

}

This compiles fine. The error begins after the file takes user input and begins to display the code. with printf statements.

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

    //Throw error is *Argv[] is not an integer
    //assuming it was an integer
    int cnt = atoi( argv[1] );
    printf( "number is %d\n", cnt );
    //
    printf("Enter %i integer values to place in tree:\n", cnt);
    for ( i1 = 0; i1 < cnt; ++i1) {
        scanf( "%d", &elemArray[i1] );
    }

    //first ouput "INput Values"

    printf( " Input Values:\n " );  
     for ( i2 = 0; i2 < cnt; ++i2) {
               printf( "%d\n", elemArray[i2] );
               printf("building tree0\n");
        }
    printf("building tree");
    TreeNode** root = malloc(sizeof(TreeNode*));
    printf("building tree");
    build_Tree(root, elemArray, cnt );
    printf("Tree Built");
    printf( "Preorder:\n ");

    //traverse
    //TreeNode* tempN = malloc(sizeof(TreeNode*));
    //tempN->data= 5;

    traverse( *root, PREORDER);             //pass the pointer of root to traverse the tree

    //traverse a single node 
    printf( "Inorder:\n ");

    printf( "Postorder:\n ");


    //Build tree with each element

    return 0;
}

void traverse( const TreeNode* root, const TraversalType type ) {

    if ( type == PREORDER) {
             if (root != NULL)
             {
                printf("%d", root->data);
                traverse( root->left, PREORDER);
                traverse( root-> right, PREORDER);
            }
    }
}




    /**
    void insertNode(TreeNode** root, TreeNode* new_node) {

       if (new_node-> data < *root-> data) {
          if (*root-> left == NULL) 
             *root-> left == new_node;
          else
            insert(*root->left, new_node);
       }

      if (new_node->data > *root->data) {
        if(*root-> right ==NULL)
          *root->right = new_node;
        else
          insert(*root->right, new_node);
      }
    }
    **/


//question1: what is the 

This is where I begin to run the code

jw8453@idaho:~/Courses/CS243/Homework/5$ make
gcc -ggdb  -c bst.c
gcc -ggdb -o bst bst.o  -lm
jw8453@idaho:~/Courses/CS243/Homework/5$ ./bst 5
number is 5
Enter 5 integer values to place in tree:
1
2
3
4
5
 Input Values:
 1
building tree0
2
building tree0
3
building tree0
4
building tree0
5
building tree0



this isnt supposed to be in the printf loop

Note: Question is a continuation of BST build tree double pointers

Community
  • 1
  • 1
arrowinfedex
  • 121
  • 1
  • 3
  • 11
  • There is no need to do `TreeNode* parent = malloc(sizeof(*parent));`, since, here `*parent` is basically a `pointer`, which is suppose to point to some node. Since root is pointing somewhere, you simply have to do `parent = root`, now `parent` will have the address of the location, where `root` is pointing at. – nIcE cOw Oct 16 '14 at 06:42
  • Would I also not need `TreeNode* current = malloc(sizeof(TreeNode));` and define `parent = current = root` – arrowinfedex Oct 16 '14 at 06:47
  • `TreeNode* newNode = malloc(sizeof(TreeNode*));` actually means, allocate a space(pointer in this case, which can hold address of TreeNode), and give the address to `newNode`. Here `sizeof(TreeNode *)` will always be `4` bytes/OS's word size. What actually is required, is space in memory for holding a `TreeNode` and return this address to `newNode`, here `sizeof(*newNode)` will be `4 + 4 + 4` bytes, for `int`, `pointer(left)` and `pointer(right)` – nIcE cOw Oct 16 '14 at 06:47
  • Before moving further, simply try to print values for both, like `printf("Size TreeNode *: %d\n", sizeof(TreeNode *));` and `printf("Size *newNode: %d\n", sizeof(*newNode));`. You will get a fair idea, what both these thingies refer to. First is for a size of a pointer, though the latter is size of `TreeNode` as a whole. – nIcE cOw Oct 16 '14 at 06:54
  • @nIcE cOw I don't know if this is relevant to the question but the tree doesn't seem to build properly although all the print statemtns execute, `traverse()` doesnt run with prints. Now, what you said is correct but the struct of `*newNode` and `TreeNode*` are the same because `typedef struct TREENODE { int data; struct TREENODE *left; struct TREENODE *right; }TreeNode;` – arrowinfedex Oct 16 '14 at 06:54
  • `*newNode` is basically what value `newNode` can point to, which in this case is a `TreeNode`(the whole structure). But `TreeNode *` means pointer to a `TreeNode`, which means, it is a pointer, which can hold an adress of a `TreeNode`. It is always equal to WORD size or `4 bytes/sizeof(int)` (For 32-bit machine) – nIcE cOw Oct 16 '14 at 06:57
  • Size TreeNode *: 8 Size *node *: 24 – arrowinfedex Oct 16 '14 at 07:01
  • Exactly, since you working on a `64-bit machine` WORD size is `8-bytes`, therefore, a pointer will always be of `8 bytes`. Though the TreeNode contains, three thingies `int`(8 bytes), `a pointer to left child`(8 bytes) and `a pointer to right child`(8 bytes). You need space for that. THe answer below, clearly states, what you doing wrong. `TreeNode *` means a pointer to struct, which will always be equal to the size of any pointer(8 bytes) – nIcE cOw Oct 16 '14 at 07:04
  • if (root == NULL) is where the error occurs – arrowinfedex Oct 16 '14 at 07:25

1 Answers1

1

This is wrong:

TreeNode* newNode = malloc(sizeof(TreeNode*));

instead

TreeNode* newNode = malloc(sizeof(TreeNode));

or

TreeNode* newNode = malloc(sizeof(*newNode));

Here:

    TreeNode* parent = malloc(sizeof(TreeNode*));
    TreeNode* current = malloc(sizeof(TreeNode*));
    parent = current = root;

you have a memory leak, you reserve space for parent and current and then you assign those variables to another address, same for:

TreeNode* newNode = malloc(sizeof(TreeNode*));
...
newNode = getN(data);

I suggest

void setN(TreeNode *node, int dataElem) {
    node->left = NULL;
    node->right = NULL;
    node->data = dataElem;
}
...
setN(newNode, data);

instead of

TreeNode* getN(int dataElem) {
    TreeNode* temp;
    temp = malloc(sizeof(TreeNode*));
    temp-> left = NULL;
    temp-> right = NULL;
    temp->data = dataElem;
    return temp;
}
...
newNode = getN(data);
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • Ok, once I changed addNodeToTree to have newNode before root = newNode and again in the else statement. Then I changed the main's malloc(sizeof(TreeNode)). I don't know how to avoid the memory leak for parent = current = root. – arrowinfedex Oct 16 '14 at 06:33
  • I changed `parent = current = root` to `*parent = *current = *root` and that fixed it – arrowinfedex Oct 16 '14 at 06:35
  • K one last question that I might move to another page if allowed, but when I build a tree how do I allocate the pointer and node spaces to create the first node(node) to addNodeToTree? Right now, I create a node in build_Tree then set those values to null. After I set the *root to node, i use a for loop for addNoteToTree with the *root. – arrowinfedex Oct 16 '14 at 07:09