0

当我尝试释放一个 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),则不仅肯定丢失的语句仍然存在,而且我会在堆摘要之前收到大量无效读取。如果有人可以为我提供帮助,我完全不知道如何解决这个问题。谢谢

4

2 回答 2

0

我猜next_token是一个字符串,并且to_lower不会创建一个新字符串。这意味着在释放仍然指向该释放内存next_token之后。item->data

于 2013-10-13T17:52:16.873 回答
0

关闭标记器,您需要某种释放ItemTypes的方法。如果您之前释放它们,标记化将读入释放的内存,这是您非常不想做的事情。

我猜你的框架应该提供某种方式来释放任何输入HM_Put. 如果没有,您需要自己执行此操作。

例如(这可以通过决定在令牌和to_lowered 令牌之间保留哪个来优化):

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();
于 2013-10-13T18:11:38.280 回答