[英]How to deallocate memory in prefix tree? (ANSI C)
I tried to deallocate memory in dict_free() function, but it doesn't work and I don't no why. 我试图在dict_free()函数中释放内存,但是它不起作用,我也不是为什么。 Am I missing something?
我想念什么吗? Can't figure out, what's wrong.
不知道怎么了。
Edit: If I call free() in dict_free() I expect to see that free'd pointer points to NULL, but that's not happening. 编辑:如果我在dict_free()中调用free(),我希望看到free'd指针指向NULL,但这没有发生。
Here is my code: 这是我的代码:
#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;
}
}
Your free code looks fine, except it will fail to free the root node. 您的免费代码看起来不错,但是它将无法释放根节点。
Your test for free-ness is wrong. 您对自由度的测试是错误的。
free
will not set any variable to NULL
. free
不会将任何变量设置为NULL
。 Often it is a good idea to do that explicitly, so you are sure not to read already freed memory: 通常,明确地执行此操作是一个好主意,因此请确保不要读取已经释放的内存:
free(d->branches[i]);
d->branches[i] = NULL; // clobber pointer to freed memory
To handle the root node issue, and probably somewhat cleaner as well, do this: 要处理根节点问题,并且可能还要更清洁一些,请执行以下操作:
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);
}
}
dict_free(d->branches[i]);
free(d->branches[i]);
printf("Is it free?? %s\n",d==NULL?"yes":"no");
This checks d, but you don't modify d in the loop. 这会检查d,但您不会在循环中修改d 。 Since you check that d is not null above, this always prints no.
由于您在上面检查d不为null,因此始终打印为no。
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
}
}
}
}
I've followed your existing code in not freeing d, but you may want to change things so a Dict is always allocated the same way (eg add a dict_new function) with dict_free also freeing the passed object. 我遵循了您现有的代码,没有释放d,但是您可能想要更改某些内容,因此Dict总是以相同的方式分配(例如,添加dict_new函数),而dict_free也释放了传递的对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.