Search code examples
csegmentation-faultred-black-tree

Struct causing segmentation fault


I am having trouble grappling this error. I am implementing a Red black tree in C and am running into segmentation fault at a particular location (line 29)

 TNODE *tree_add(TNODE *root, const KEY k, const VALUE v) {
        LNODE *lnode = NULL;
        if (root == NULL) {
                TNODE *node = talloc(k);
                lnode = lalloc(v);
                node->head = lnode;
                node->tail = lnode;
                node->is_red = true;
                return node;
        }
        if (strcmp(k, root->key) < 0) { 
                root->left = tree_add(root->left, k, v);
        } else if (strcmp(k, root->key) > 0) {  
                root->right = tree_add(root->right, k, v);
        } else {
                if (strcmp(k, root->key) == 0) {
                        lnode = lalloc(v);
                        root->tail->next = lnode;
                        root->tail = lnode;
                        root->tail->next = NULL;
                }
        }
        if (is_red(root->right) && !is_red(root->left)) { //is_red seg faulting
                root = rotate_left(root);
        }
        if (is_red(root->left) && is_red(root->left->left)) {
                root = rotate_right(root);
        }
        if (is_red(root->left) && is_red(root->right)) {
                flip_colors(root);
        }
        return root;

}

Here is the is_red function:

bool is_red(const TNODE *h) { 
    bool is_red = h->is_red;
    return is_red;

}

Before implementing the last three if statements to convert BST to RB tree, the code works fine. What is weird is that when I debugged is_red, the variable is_red comes up as true. So that means I am not accessing restricted memory. However, I get a seg fault as soon as I return from is_red function and intotree_add.

For further clarification, here is the TNODE struct:

 typedef struct tnode {
  KEY key;             // Search key for this binary search tree node.
  struct tnode *right; // Right child.
  struct tnode *left;  // Left child.

  LNODE *head; // Head of the linked list storing the values for the search key.
  LNODE *tail; // Tail of the linked list storing the values for the search key.

  bool is_red; // Flag use only in red-black trees to denote redness.
} TNODE;

Solution

  • You want to make sure the right child and left child exist before you do the IS_RED check: Replace

    if (is_red(root->right) && !is_red(root->left)) //is_red is giving me seg fault
    

    with

    if (root->right && is_red(root->right) && root->left && !is_red(root->left)) 
    

    Please also do the similar check to other places.