Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Traversing a binary tree in C

I'm trying to traverse a binary tree in C. My tree contains an AST node (abstract syntax tree node for compiler). ASTnode reserves nodetype which specifies given node's type (i.e INT OP or CHAR and TYPE we don't need to concern other types), the other members are left and right pointers, and finally we store.

Here is code for traversing:

    void traverse(struct ASTNode *root)
    {
        if(root->nodeType == OP){
            printf("OP \n");
            if(root->left != NULL){
              printf("left - ");
              traverse(root->left);
            }
            if(root->right != NULL){
              printf("right - ");
              traverse(root->right);
            }
            return;
        }
        else{
            if(root != NULL && root->nodeType == INT)
            {
              printf("INT - ");
              printf("INT: %d\n",root->value);
            }
            if(root != NULL && root->nodeType == CHAR)
            {
              printf("CHAR - ");
              printf("CHAR: %c\n",root->chValue);
            }
            return;
        }
    }

Also we can't assign left or right values to CONSTANT nodes because in AST, constant values don't contain any extra values.

Updated:

The problem is in my main call:

    int main()
    {
        struct ASTNode *node1 = makeCharNode('a');
        struct ASTNode *node2 = makeCharNode('b');
        struct ASTNode *node10 = makeCharNode('c');
        struct ASTNode *node3 = makeINTNode(19);

        struct decl *d = (struct decl*) malloc(sizeof(struct decl*));
        struct decl *d2 = (struct decl*) malloc(sizeof(struct decl*));

        struct ASTNode *node4 = makeNode(3,d,node3,node2);
        struct ASTNode *node5 = makeNode(3,d2,node4,node1); !!
        traverse(node4);
    }

If we delete node5 (which is marked by !!) the code works very well otherwise it gives a segmentation fault.

Functions that operate on makenode:

    struct ASTNode *makeNode(int opType,struct decl *resultType,struct ASTNode *left,struct ASTNode *right)
    {
        struct ASTNode *node= (struct ASTNode *) malloc(sizeof(struct ASTNode *));
        node->nodeType = opType;
        node->resultType = resultType;
        node->left = left;
        node->right = right;
        return node;
    }

    struct ASTNode *makeINTNode(int value)
    {
        struct ASTNode *intnode= (struct ASTNode *) malloc(sizeof(struct ASTNode *));
        intnode->nodeType = INT;
        intnode->value = value;
        return intnode;
    }

    struct ASTNode *makeCharNode(char chValue)
    {
        struct ASTNode *charNode = (struct ASTNode *) malloc(sizeof(struct ASTNode *));
        charNode->nodeType = CHAR;
        charNode->chValue = chValue;
        return charNode;
    }
like image 213
iva123 Avatar asked Dec 06 '22 04:12

iva123


1 Answers

Your mallocs are wrong

 struct decl *d = (struct decl*) malloc(sizeof(struct decl*));
 struct decl *d2 = (struct decl*) malloc(sizeof(struct decl*));

need to be

 struct decl *d = (struct decl*) malloc(sizeof(struct decl));
 struct decl *d2 = (struct decl*) malloc(sizeof(struct decl));

(or use sizeof *d instead of sizeof(struct decl)). In C you don't need to cast the return value of malloc , btw.

Also, make sure you're setting members to NULL or another default value before you access them. malloc will not set them to 0/NULL for you.

like image 108
nos Avatar answered Dec 23 '22 13:12

nos