2016-10-13 4 views
0

У меня есть программа C, которая реализует деревья. моя функция очистки выглядит следующим образом:Невозможно освободить память от функции

void cleanup_tree(TreeNode* root){ 
     printf("Called\n"); 
     if(root->left!=NULL){ 
       cleanup_tree(root->left); 

     } 

     if(root->right!= NULL){ 
       cleanup_tree(root->right); 
     } 

     if(root->right==NULL &&root->left==NULL) { 
       /*free(root);*/ 
       free(root->word); 
       free(root); 
       root = NULL; 
     } 

} 

My Tree структура имеет

typedef struct TreeNode_st { 
    char *word;     // the word held in this node 
    unsigned int frequency;  // how many times it has been seen 
    struct TreeNode_st *left;  // node's left child 
    struct TreeNode_st *right; // node's right child 
} TreeNode; 

Я Инициирование дерево, как это:

TreeNode* initTreeNode(){ 
     TreeNode *mainNode=  (TreeNode*)malloc(sizeof(TreeNode)); 
     mainNode->frequency = 0 ; 
     mainNode->word = NULL; 
     mainNode->left = NULL; 
     mainNode->right = NULL; 
     return mainNode; 

} 

в моем main, я назвал

TreeNode *mainNode =initTreeNode(); 

, и я делаю операции на нем, и непосредственно перед выходом из программы, я назвал

утечки памяти
cleanup_tree(mainNode); 

Valgrind сообщил, так просто для проверки, я сделал я поставил
printf("~~~FINAL NULL TEST %s",mainNode->left->right->word); ниже моей cleanup_tree линии, И я могу видеть это слово даже сейчас.

Что я делаю неправильно?

+0

Похож на 'if (root-> right == NULL && root-> left == NULL) {' только освобождает узлы без детей? –

+0

Я вызываю эту функцию рекурсивно, поэтому она должна идти по краям, устанавливать их бесплатно, поэтому родитель теперь будет узлом, у которого нет детей, и он будет доходить до корня –

+0

. Переменные не настраивают себя волшебным образом к 'NULL'. – tkausl

ответ

1

Есть два способа:

  1. Вы передаете ему указатель на а-указатель: void cleanup_tree(TreeNode **root)
  2. Вы установили поля в NULL после возвращения очистки:

В настоящее время, изменения, внесенные этой функцией, не отражаются в параметре узла, который вы передали.

объявления 2:

cleanup_tree(root->right); 
root->right= NULL; 
0

Вы, кажется, под впечатлением, что установка root = NULL в конце этой функции будет отображаться в вызывающей функции, так что третий if блок вызывается. Это не так.

Вы хотите всегда free()word, а также сам узел.

void cleanup_tree(TreeNode* root){ 
     printf("Called\n"); 
     if(root->left!=NULL){ 
       cleanup_tree(root->left); 
     } 

     if(root->right!= NULL){ 
       cleanup_tree(root->right); 
     } 
     free(root->word); 
     free(root); 
} 
+0

, когда я удалил мой if (левый узел и правый узел оба были нулевыми), я получаю ошибку сегментации –

+0

@harvey_slash Тогда должна быть какая-то другая проблема. Что говорит вальгринд? – dbush

+0

@ Ответ Paul Ogilvie работал, , если im установить слева и справа на NULL, valgrind счастлив –

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