Thread: Tree help please..

  1. #1
    Registered User
    Join Date
    Jan 2011
    Location
    Mississauga
    Posts
    10

    Tree help please..

    Hi All,

    I make a BinarySearchTree implementation and it reads the a txt with more than 50000 inputs. It compiles perfectly but when I run it.. It gives me segmentation fault error, this program is simple to understand yet the Segmentation Fault error is so confusing since it does not explain what's the error is.. I was thinking there might be something wrong with the pointers, but I have been debugging for more than 2 days now and I couldn't find my error with the pointers.. Would someone explain what I did wrong? Here is my code..

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct BSTree *BST;
    
    struct BSTree {
        int elm;
        BST left;
        BST right;
    };
    
    BST initiateTree(BST T) {
        if(T != NULL) {
            initiateTree(T->left);
            initiateTree(T->right);
            free(T);
        }
    }
    
    BST insertTree(int a, BST T) {
        if(T == NULL) {    
            T = malloc(sizeof(struct BSTree));
            if(T == NULL) {
                fprintf(stderr, "insert: FATAL - malloc failed!\n");
            } else {
                T->elm = a;
                T->left = T->right = NULL;
            }
        } else {
            if(a < T->elm) {
                T->left = insert(a, T->left);
            } else {
                if(a > T->elm) {
                    T->right = insert(a, T->right);
                }
            }
        }
        return T;
    }
    
    main() {
        BST T;
        int element;
        FILE *fp;
    
        T = initiateTree(NULL);
        if((fp = fopen("data_search.txt", "r")) == NULL) {
            printf("main: FATAL - Failed to open data_search.txt!\n");
            return 0;
        } else {
            printf("main: Success to open data_search.txt\n");
    
            while(!feof(fp)) {
                element = getc(fp);
                insertTree(element, T);
            }
        }
    }
    Thank you so much..

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    Well you're ignoring the return result of insert() at the moment.

    Also, your init function is supposed to return a result, and it doesn't.

    Increase the warning level on your compiler until it complains about both issues. If it does already warn you, and you're ignoring those warnings, then you're on your own.

    seg-fault means you tried to access memory you don't own. There are MANY reasons for this, including
    - dereferencing an uninitialised pointer
    - dereferencing NULL
    - not allocating enough memory, and stepping off the end
    - stepping off the end of an array
    - using memory after you have freed it
    - freeing something more than once
    - freeing something that wasn't allocated to begin with

    Dereferencing NULL is pretty much guaranteed to fault on modern hardware, but everything else can be pretty random.
    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.

  3. #3
    Registered User
    Join Date
    Jan 2011
    Location
    Mississauga
    Posts
    10
    Hi Salem,

    Thank you for your reply.. As you mentioned before, I stored the return of insert() to the struct (T). Also, changed the main() to int main() that returns 0 at the last part.. I also checked and revised my code logic against your seg-fault error checklist, however, I still get the seg-fault error.. Would you explain a little bit more detail what si the error is in this small program? I attached my revised code here..

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct BSTree *BST;
    
    struct BSTree {
    	int elm;
    	BST left;
    	BST right;
    };
    
    BST makeEmpty(BST T) {
    	if(T != NULL) {
    		makeEmpty(T->left);
    		makeEmpty(T->right);
    		free(T);
    	}
    }
    
    BST insert(int a, BST T) {
    	if(T == NULL) {	
    		T = malloc(sizeof(struct BSTree));
    		if(T == NULL) {
    			fprintf(stderr, "insert: FATAL - malloc failed!\n");
    		} else {
    			T->elm = a;
    			T->left = T->right = NULL;
    		}
    	} else {
    		if(a < T->elm) {
    			T->left = insert(a, T->left);
    		} else {
    			if(a > T->elm) {
    				T->right = insert(a, T->right);
    			}
    		}
    	}
    	return T;
    }
    
    int main() {
    	BST T;
    	int element, i;
    	FILE *fp;
    	
    	T = makeEmpty(T);
    	if((fp = fopen("data_search.txt", "r")) == NULL) {
    		printf("main: FATAL - Failed to open data_search.txt!\n");
    		return 0;
    	} else {
    		printf("main: Success to open data_search.txt\n");
    
    		while(!feof(fp)) {
    			element = getc(fp);
    			T = insert(element, T);
    		}
    	}
    	return 0;
    }
    Thank you so much..

  4. #4
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    Like Salem said "freeing something that wasn't allocated to begin with" will cause a seg fault which is the case here.

    You are using makeEmpty before T is initialized. When using pointers, you should follow the guideline that a pointer should always point to a) valid memory or b) NULL. When you call makeEmpty, T is pointing to garbage. You can google "dangling pointers" for more information about why this is bad.
    Don't quote me on that... ...seriously

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Now fix the warnings related to your makeEmpty function. What do you want it to return, if anything, and what do you intend to pass into it?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Registered User
    Join Date
    Jan 2011
    Location
    Mississauga
    Posts
    10
    Hi All,

    Thanks for the advice from Brad0407 and iMalc, the intention to have makeEmpty() is to initialize a pointer but it is a bad practice to have a pointer that point to garbage.. So I get rid of it and initialize the pointer in the while(!feof(fp)) {}.. But it still gives me segmentation fault, yet I could not find other logic error(s).. Is there any stupid mistakes that I do in this program? Thank you..

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Well, you shouldn't be using feof to control a loop: Cprogramming.com FAQ > Why it's bad to use feof() to control a loop.

  8. #8
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    I doubt that you want to initialize the pointer in the while loop. That will destroy your tree every iteration. And by initialize the pointer, I assume you mean:
    Code:
    T = NULL;
    Don't quote me on that... ...seriously

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Binary Tree Search
    By C++Newbie in forum C++ Programming
    Replies: 7
    Last Post: 04-05-2011, 01:17 AM
  2. Interpreter.c
    By moussa in forum C Programming
    Replies: 4
    Last Post: 05-28-2008, 05:59 PM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. BST/Red and Black Tree
    By ghettoman in forum C++ Programming
    Replies: 0
    Last Post: 10-24-2001, 10:45 PM