当我试图释放一个malloc的对象时,运行valgrind似乎暗示我让事情变得更糟。例如,这是我的代码:
for(next_token = TKGetNextToken(tokenizer); next_token != NULL; next_token = TKGetNextToken(tokenizer))
{
ItemType* item = malloc(sizeof(ItemType));
item->data = to_lower(next_token);
item->fileName = filename;
item->occ = 1;
HM_Put(hm, item);
free(next_token);
}
现在,通过上面的代码,我被告知字节肯定会丢失在item是malloc的行上。但是,如果我在free(next_token)下添加free(item),那么不仅会保留那个肯定丢失的语句,而且我会在堆摘要之前收到大量的无效读取。如果有人能给我一些帮助,我完全不知道如何解决这个问题。感谢
答案 0 :(得分:0)
我猜next_token
是一个字符串,to_lower
不会创建新字符串。这意味着在释放next_token
之后item->data
仍指向那个自由的记忆。
答案 1 :(得分:0)
关闭令牌化程序后,您需要一些方法来释放ItemType
。如果你之前释放它们,标记化将读入释放的内存,这是你不想做的事情。
我想你的框架应该提供一些方法来释放任何被送入HM_Put
的东西。如果没有,你需要自己做。
例如(这可以通过决定在令牌和to_lower
ed令牌之间保持哪个来优化:
typedef struct t_tofree {
struct t_tofree *next;
ItemType *item;
char *token; // Maybe superfluous if item->data points here...
};
t_tofree *toFree = NULL;
void mustFree(ItemType *item, char *token) {
t_tofree *new = malloc(sizeof(t_tofree));
new->next = toFree;
new->item = item;
new->token = token;
toFree = new;
}
void freeAll() {
while (toFree) {
t_toFree *next = toFree->next;
free(toFree->token); toFree->token = NULL;
// The line below if token is *not* data and both were allocated.
free(toFree->item->data; toFree->item->data = NULL;
// Other cleanup on item?
free(toFree->item); toFree->item = NULL;
free(toFree); toFree = next;
}
}
...
for(next_token = TKGetNextToken(tokenizer); next_token != NULL; next_token = TKGetNextToken(tokenizer))
{
ItemType* item = malloc(sizeof(ItemType));
item->data = to_lower(next_token);
item->fileName = filename;
item->occ = 1;
HM_Put(hm, item);
// Probably you can free next_token here, and only store item->data
mustFree(item, next_token);
}
...
// Here you're REALLY REALLY sure you won't use tokens or items
// (it's agreed that TKGetNextToken returns alloc'ed memory)
freeAll();