Home > Software design >  Remove elements from a binary search tree based on a condition
Remove elements from a binary search tree based on a condition

Time:09-17

I have a Struct that stores the name of a file and the day it was last accessed.

typedef struct sFile {
   int lastAccess;
   char name[50];
} File;

typedef struct sNode {
   File info;
   struct sNode* left;
   struct sNode* right;
} Node;

I coded a function that recursively removes files that have their access day less than a certain number. For example, when you call this function and pass 10 as a parameter, all files that have access day less than 10 will be deleted.

However, I'm having problems with the execution of the same and ends up generating a memory access error.

I believe my insertion and removal functions are correct but just in case I'm leaving them below.

Insert and Delete Functions:

void insert(Node **root, File value) {
   if(*root == NULL) {
      Node *celula = getNode();
      
      if(celula == NULL) {
         printf("\nERRO: Falha na alocacao de memoria. Encerrando programa.\n");
         exit(1);
      }

      celula->left = NULL;
      celula->right = NULL;
      celula->info = value;
      *root = celula ;
   } else {
      if(strcmp(value.name, (*root)->info.name) < 0) {
         insert(&(*root)->left, value);
      } else {
         insert(&(*root)->right, value);
      }
   }
};

Node* deleteNode(Node *root, char name[50]) {
    if (root == NULL)
        return root;
 
    if (strcmp(name, root->info.name) < 0)
        root->left = deleteNode(root->left, name);
 
    else if (strcmp(name, root->info.name) > 0)
        root->right = deleteNode(root->right, name);
 
    else {
        if (root->left == NULL) {
            Node *temp = root->right;
            free(root);
            return temp;
        }
        else if (root->right == NULL) {
            Node *temp = root->left;
            free(root);
            return temp;
        }
 
        Node *temp = minValueNode(root->right);
 
        root->info = temp->info;
 
        root->right = deleteNode(root->right, temp->info.name);
    }
    return root;
}

Tree cleaning function:

Node* clear(Node *root, int date) {
   if(root == NULL) {
      return NULL;
   }

   if(root->info.lastAccess <= date) {
      root = deleteNode(root, (root)->info.name);
   }

   root = clear(root->left, date);
   root = clear(root->right, date);

   return root;
}

Error Message:

[1]    39970 segmentation fault (core dumped)  ./7.out

Does anyone have any idea what might be causing this error and how I can fix it?

CodePudding user response:

I'd recommend running valgrind, gdb, etc, to try and figure out where exactly the error is, but without that info here is where I can see a possible NULL dereference.

If root->left and root->right are both NULL, then deleteNode will return NULL, which is then dereferenced by the calls to clear(root->left, date).

See if inserting a check for NULL there would make it no longer segfault.

Again, impossible to tell here if that is what's causing it, please also provide the rest of the code to make it runnable, or debug it to find out what line is causing the segfault.

CodePudding user response:

I was able to find the error. Thanks to everyone who helped.

I was returning NULL to the root of the tree, so I lost all tree reference and consequently performed an improper memory access. I updated the clear function to the following:

Node* clear(Node *root, int date) {
   if(root == NULL) {
      return NULL;
   }

   if(root->info.lastAccess <= date) {
      root = deleteNode(root, (root)->info.name);
   }

   root->left = clear(root->left, date);
   root->right = clear(root->right, date);

   return root;
}
  • Related