Search code examples
ctreebinary-treecoredump

Binary Tree Segmentation fault (core dumped)


struct Tree{
    char string[30];
    int hmanyt;
    struct Tree * left;
    struct Tree * right;
};
typedef struct Tree * drzewo;
void printftree(drzewo* korzen)
{
    if((*korzen)->left != NULL)
        printftree(&((*korzen)->left));
    printf("%s(%d)\n",(*korzen)->string,(*korzen)->hmanyt);
    if(strcmp((*korzen)->string,"boril\0")==0)
        (((*korzen)->right)->left)->left=NULL;
    if((*korzen)->right != NULL)
        printftree(&((*korzen)->right));
    return ;
}
void erease(drzewo* korzen)
{
    if((*korzen)->left==NULL && (*korzen)->right==NULL)
    {
        *korzen=NULL;
        free (*korzen);
        return ;
    }
    else
    {
        if((*korzen)->left !=NULL)
        {
            erease(&((*korzen)->left));
            (*korzen)->left=NULL;
            free((*korzen)->left);
        }
        if((*korzen)->right !=NULL)
        {
            erease(&((*korzen)->right));
            (*korzen)->right=NULL;
            free((*korzen)->right);
        }
    }
    *korzen=NULL;
    free(*korzen);
    return ;
}
void add(drzewo* korzen,char word[])
{
    while(*korzen!=NULL)
    {
        if(strcmp((*korzen)->string,word)==0)   {
            ((*korzen)->hmanyt)++;
            return; }
        else if(strcmp((*korzen)->string,word)<0)   {
            korzen=&((*korzen)->right); }
        else if(strcmp((*korzen)->string,word)>0)   {
            korzen=&((*korzen)->left);
                }
    }
    *korzen=(drzewo) malloc(sizeof(drzewo));
    strcpy(((*korzen)->string),word);
    printf("%p",(*korzen)->left);
    printf("%p\n",(*korzen)->right);
    (*korzen)->hmanyt=1;    
    return;
}
int main()
{
    drzewo korzen =NULL;
    char *words[10]={"alfabet","borixon","aaaaaa","zombie","bobas","kamil","agnieszka","kokos","zamach"};
    for(int i=0;i<9;i++)
        add(&korzen,words[i]);
    printf("test1\n");
    printftree(&korzen);
    printf("test");
    erease(&korzen);
    return 0;
}

So this is my implementation of binary tree. Which loads 10 words to the tree . Sadly during 'printing' this tree I came across a problem which is core dumped. I don't know why but one of the structurs "has" (*korzen)->left that isn't NULL, my funcion wants to acess it,and the core dumped appears. After adding two lines

if(strcmp((*korzen)->string,"boril\0")==0)
    (((*korzen)->right)->left)->left=NULL;

it works fine, but I don't know why i have this issue. Another issue is that despite having such a line as:

(*korzen)->hmanyt=1;

Afterall it doesn't have this value ... (only first word has hmanyt==1) . Help would be really appreciated.


Solution

  • It is a bad idea to assign NULL to a pointer which you want to free. Change place of *korzen=NULL; and free(*korzen); in your function erease:

    Adapt your function erease like this:

    void erease(drzewo* korzen)
    {
        if ( *korzen == NULL )
            return;
    
        if( (*korzen)->left !=NULL )
        {
            erease(&((*korzen)->left)); // (*korzen)->left is freed in erease
        }
        if( (*korzen)->right !=NULL )
        {
            erease(&((*korzen)->right)); // (*korzen)->right is freed in erease
        }
        free(*korzen);
        *korzen=NULL;
        return;
    }
    

    If you insert a new node in your tree you have to initialize its childs (*korzen)->left and (*korzen)->right with NULL. Further the type of drzewo is struct Tree*, so sizeof(drzewo) gives the size of a pointer not the size of struct Tree.

    void add(drzewo* korzen,char word[])
    {
        while( *korzen != NULL )
        {
            int cmp = strcmp( ( *korzen )->string, word );
            if ( cmp == 0 )
            {
                ((*korzen)->hmanyt)++;
                return;
            }
            else if( cmp<0 ) {
                korzen=&((*korzen)->right);
            }
            else if (cmp>0 ) {
                korzen=&((*korzen)->left);
            }
        }
        // allocate new node and initiialize
        *korzen=malloc(sizeof(struct Tree)); // allocat sizeof struct Tree ( not sizeof pointer to Tree) 
        ( *korzen )->left = NULL;  // <- left child is null
        ( *korzen )->right = NULL; // <- right child is null
        strcpy(((*korzen)->string),word);
        (*korzen)->hmanyt=1;    
        return;
    }
    

    Finally your function printftree:

    void printftree(drzewo* korzen)
    {
        if ( *korzen == NULL )
            return;
        if( (*korzen)->left != NULL)
            printftree(&((*korzen)->left));
        printf("%s(%d)\n",(*korzen)->string,(*korzen)->hmanyt);
        if((*korzen)->right != NULL)
            printftree(&((*korzen)->right));
        return ;
    }