2010-09-22 56 views
1

我試圖釋放dict_free()函數中的內存,但它不起作用,我不知道爲什麼。我錯過了什麼嗎?無法弄清楚,什麼是錯的。如何釋放前綴樹中的內存? (ANSI C)

編輯: 如果我在dict_free()中調用free(),我希望看到free'd指針指向NULL,但這不會發生。

這裏是我的代碼:

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

typedef struct Dict 
{ 
    struct Dict *branches[256]; 
    int index; 

}Dict; 


void dict_insert_depth(unsigned char*,Dict *,int); 
void dict_insert(unsigned char*,Dict *); 

void dict_free(Dict *d) 
{ 
    if(d!=NULL){ 
    int i; 
    for(i=0; i<256; i++){ 
     if(d->branches[i] != NULL){ 
     dict_free(d->branches[i]); 
     free(d->branches[i]); 
     printf("Is it free?? %s\n",d==NULL?"yes":"no"); 
     } 
    } 
    } 
} 
/** 
* Insert word into dictionaR 
*/ 
void dict_insert(unsigned char *w, Dict *d) 
{ 
    dict_insert_depth(w,d,0); 
} 

void dict_insert_depth(unsigned char *w, Dict *d, int depth) 
{ 
    if(strlen(w) > depth){ 
    int ch = w[depth]; 

    if(d->branches[ch]==NULL){ 
     d->branches[ch] = malloc(sizeof(struct Dict)); 
     dict_insert_depth(w,d->branches[ch],depth+1); 

    }else{ 
     dict_insert_depth(w,d->branches[ch],depth+1); 
    } 
    } 
} 

/** 
* Check whether a word exists in the dictionary 
* @param w Word to be checked 
* @param d Full dictionary 
* @return If found return 1, otherwise 0 
*/ 
int in_dict(unsigned char *w, Dict *d) 
{ 
    return in_dict_depth(w,d,0); 
} 

int in_dict_depth(unsigned char *w, Dict *d, int depth) 
{ 
    if(strlen(w)>depth){ 
    int ch = w[depth]; 
    if(d->branches[ch]){ 
     return in_dict_depth(w, d->branches[ch], depth+1); 
    }else{ 
     return 0; 
    } 
    }else{ 
    return 1; 
    } 

} 
+1

'不起作用'是什麼意思?謹慎提供更多細節,瞭解正在發生的事情以及您的期望? – 2010-09-22 22:34:59

回答

3

你免費的代碼看起來不錯,但它將無法釋放根節點。

你對自由度的測試是錯誤的。 free不會將任何變量設置爲NULL。通常,這是一個好主意,做的是明確的,所以你一定不要看已經釋放的內存:

free(d->branches[i]); 
    d->branches[i] = NULL; // clobber pointer to freed memory 

要處理根節點的問題,而且可能有些清潔劑爲好,這樣做:

void dict_free(Dict *d) 
{ 
    if(d!=NULL){ 
    int i; 
    for(i=0; i<256; i++){ 
     if(d->branches[i] != NULL){ 
     dict_free(d->branches[i]); 
     d->branches[i] = NULL; 
     } 
    } 
    free(d); 
    } 
} 
0
dict_free(d->branches[i]); 
free(d->branches[i]); 
printf("Is it free?? %s\n",d==NULL?"yes":"no"); 

這將檢查d,但你不會在環路修改d。由於您檢查不是上面的空,它總是打印否。

void dict_free(Dict* d) { 
    if (d) { 
    for(int i = 0; i < 256; i++) { 
     if (d->branches[i]) { 
     dict_free(d->branches[i]); 
     free(d->branches[i]); 

     d->branches[i] = 0; // mark this branch as freed 
     // important if d is reused, and since dict_free doesn't 
     // free(d), it could be 
     } 
    } 
    } 
} 

我已經按照你的現有代碼不釋放d,但你可能要改變的事情,這樣的字典總是被分配以同樣的方式(如添加dict_new功能)與dict_free也釋放傳遞目的。