Thread: Variable Changes Value Unexpectedly (Binary Tree)

  1. #1
    Registered User
    Join Date
    Mar 2017
    Posts
    1

    Variable Changes Value Unexpectedly (Binary Tree)

    Hello. I'm having some issues with an assignment here. In my LOAD function, the root is being overwritten on each pass of the for loop.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
        
    struct myTree
    {
        char *first;
        char *last;
        long number;
        struct myTree *right, *left;
    };
        
    typedef struct myTree node;
        
    int SCAN(FILE *(*stream))
    {
        int size = 0;
        *stream = fopen("hw9.data", "r");
        char *buffer = NULL;
        size_t bufsize = 0;
        size_t temp = getline(&buffer, &bufsize,*stream);
        
        //Increment size for each line break until the end of the file
        while(!feof(*stream))
        {
            size++;
                
            temp = getline(&buffer, &bufsize, *stream);
        }
        
        return size;
    }
        
    void INSERT(node *(*tree), node *item)
    {
        if(!*tree)
        {
           *tree = item;
            return;
        }
        else
        {
            if(strcmp((*tree)->first, item->first) < 0)
            {
                 INSERT(&(*tree)->left, item);
            }
            else
            {
                INSERT(&(*tree)->right, item);
            }
        }
    }
        
    void LOAD(FILE *stream, int size, node *(*root))
    {
        int i;
        char *tempText;
        size_t lineLen;
        node *item = (node *)malloc(sizeof(node));
        
        rewind(stream);
        
        getline(&tempText, &lineLen, stream);
        item->first = strtok(tempText, " ");
        item->last = strtok(NULL, " ");
        item->number = (long)strtok(NULL, "\n");
        *root = item;
        
        for(i = 0; i < size + 1; i++)
        {
            printf("\n\n%s\n\n", item->first);
            if(i == 0){
                *root = item;}
            //INSERT(root, item);
        
            printf("\n\nroot %s\n\n", (*root)->first);
       
            getline(&tempText, &lineLen, stream);
            item->first = strtok(tempText, " ");
            item->last = strtok(NULL, " ");
            item->number = (long)strtok(NULL, "\n");
        }
            
        fclose(stream);
    }
        
    void FREE(node *tree)
    {
        if(tree == NULL)
        {
            return;
        }
        
        FREE(tree->left);
        FREE(tree->right);
      
        free(tree);
    }
        
    int main(void) {
            int size;
            FILE *stream;
            node *tree = NULL;
               
            size = SCAN(&stream);
            LOAD(stream, size, &tree);
               
            system("clear");
             
            //Print statements not needed to show errors.
            /*printf("\nPRE_ORDER\n");
            printf("--------------\n");
            PRE_ORDER(tree);
               
            printf("\nIN_ORDER\n");
            printf("--------------\n");
            IN_ORDER(tree);
               
            printf("\nPOST_ORDER\n");
            printf("--------------\n");
            POST_ORDER(tree);*/
              
            FREE(tree);
            tree = NULL;
        
            return 0;
    }

    Here is my data file:


    Code:
    ronald johnson 7774013
    john ronson 7774014
    tomas smith 7774015    
    won ton 7774016

    On loop iteration 1, the root is correctly assigned as ronald. On iteration 2, it is reassigned to john, then on iteration 3, it is reassigned to tomas, and so on.


    How can I correct this issue?

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Where do you allocate space for the memory used by C-Strings needed by "first" and "last" fields in struct myTree?

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Some points.
    1. Upper case names for function names is not standard practice. UPPERCASE is usually reserved for #define constants. Use Initialcaps or CamelCase for function names.

    2. malloc doesn't clear memory, so your left/right pointers are garbage by default. This is really important since you typically test for NULL to see if you've reached a leaf.

    3. As pointed out by stahta01, strtok doesn't make a copy of your strings. What you end up with is multiple pointers all pointing at the same string fragment, in a "last one wins" situation.

    The whole getting the file length is a waste of time, and your code is broken when given an empty file.
    Code:
    while ( getline(&tempText, &lineLen, stream) ) {
      // allocate a node
      // tokenise and make proper copies of your data
      // insert into tree
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 09-07-2013, 04:35 AM
  2. variable value changed unexpectedly
    By johnsack in forum C Programming
    Replies: 2
    Last Post: 03-08-2012, 11:27 AM
  3. Replies: 2
    Last Post: 08-01-2007, 01:08 PM
  4. Replies: 0
    Last Post: 11-04-2006, 11:07 AM
  5. display tree data in binary tree format
    By xddxogm3 in forum C++ Programming
    Replies: 4
    Last Post: 12-11-2003, 12:47 AM

Tags for this Thread