2015-06-10 2 views
1

Я пытаюсь реализовать двоичное дерево поиска на C, более конкретно ищущее предшественника. Однако всякий раз, когда я пытаюсь запустить программу, я получаю хранилище сегментации. Вот код, о котором идет речь:Ошибка сегментации при использовании оператора if с указателями (дерево BST)

#include <stdio.h> 
 
#include <stdlib.h> 
 

 
struct tree 
 
{ 
 
    int a; 
 
    tree *left; 
 
    tree *right; 
 
    tree *prev; 
 
}*root=NULL; 
 

 
tree *searchSpecific (tree *root, int val) 
 
{ 
 
    tree *x=root; 
 
    if (!x) 
 
    { 
 
     return NULL; 
 
    } 
 
    else 
 
    { 
 
     while(x && val!=x->a) 
 
     { 
 
      if (val>x->a) 
 
       x=x->left; 
 
      else x=x->right; 
 
     } 
 
    } 
 
    return x; 
 
} 
 

 
int previous(tree *root, int f) 
 
{ 
 
tree *x=searchSpecific(root,f); 
 
    if(x->left) 
 
    { 
 
     x=x->left; 
 
     while(x->right) x = x->right; 
 
     return x->a; 
 
    } 
 

 
    tree *temp; 
 
    do 
 
    { 
 
     temp = x; 
 
     x = x->prev; 
 
    } while(x && (x->right != temp)); 
 
    return x->a; 
 
}

появляется выдаёт ошибку сегментации, если заявление, если (x-> слева) и в предыдущей функции(). Я хочу проверить, существует ли этот узел, но программа терпит крах каждый раз, и я не знаю, что с ним не так.

ответ

0

С searchSpecific может вернуться NULL, вам необходимо защитить свой код от него и проверить x перед обращением к одному из своих членов:

tree *x=searchSpecific(root,f); 
if (x != NULL && x->left) 
+0

Недостаточно: сбой падает, но снова укусы: 'do {temp = x; x = x-> prev; ... '. Еще одна иллюстрация того, как «do/while» петли в основном сломаны. – chqrlie

+0

Спасибо за помощь. В конце я добавил «x! = NULL» в первый «if()» и поставил цикл «do ... while» в оператор «if (x)», и он исправил все выпущенные. – Arattor

0

неисправность сегментации может появиться по нескольким причинам, таким как:

  • х не определено, что может быть вызвано вашей функцией * searchSpecific
  • х NULL, потому что ваша функция возвращает указатель NULL
  • x-> левая NULL, что означает попытку доступа к ней вызывает что-то плохое случится

Итак, как я буду идти об этом будет пытаться проверить, если возвращаемый дерево является пустым, используя простой, если заявление следующим образом:

if (x == NULL) { 
    /* throw error or not found message */ 
} 

Я хотел бы также предложить вам динамически выделять память для дерева, прежде чем делать что-либо с ним, путем создания многоразовой FUNC как create_tree() со следующим кодом:

tree create_tree(int data) { 
    tree *x; 
    x = malloc(sizeof(tree)); 
    x->a = data; 
    x->left = x->right = x->prev = NULL; 
    return x; 
} 

Почему? Обратите внимание, что в ваших фрагментов кода, вы просто объявить

tree *some_tree_name; 

что очень опасно каждый раз, когда вы пытаетесь сделать что-то с ним, и это может привести к коду сбой на вас на делать/в то время как петля позже.

+0

Благодарим вас за подсказки. Как я уже сказал в другом комментарии, я добавил выражение if (x) вокруг цикла do do while while и 'x! = NULL' в уже существующую 'if (()' .I ' Обязательно помните о динамическом распределении :). – Arattor

Смежные вопросы