2013-10-13 3 views
0

Когда я пытаюсь освободить объект, который является malloc'd, выполнение 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); 
     } 

Теперь, приведенный выше код, я получаю рассказанные байт определенно потеряли на линии, где malloc'd пункт. Однако, если я добавлю бесплатный (элемент) под свободный (next_token), остается не только этот явно потерянный оператор, но я получаю большое количество недопустимых чтений перед сводкой кучи. Я совершенно не понимаю, как это исправить, если кто-нибудь может мне помочь. Спасибо

+9

Добавление 'free' в случайных местах не исправит вашу программу. Вам нужно подумать о времени жизни каждого объекта, который вы выделите, и поместить свой 'free' соответственно. Valgrind может рассказать вам, какие ассигнования не освобождены, но не там, где вы должны были их освободить. –

+0

Какова основная структура данных 'tokenizer'? – Henrik

ответ

0

Я предполагаю, что next_token является строкой, и что to_lower не создает новую строку. Это означает, что после освобождения next_tokenitem->data все еще указывает на эту свободную память.

+0

Фактически: char * to_lower (char * str) { \t char * новый_str = malloc (sizeof (str) +1); \t return new_str; } ПРИМЕЧАНИЕ. Я пропустил необязательные части to_lower, но я пытался выяснить, как освободить new_str. – user2266603

+1

@ user2266603 Ну, у вас есть * большая * проблема в вашей функции 'to_lower', тогда вы выделяете только пробел * для указателя *. Оператор 'sizeof' вернет размер указателя, а не то, на что указывает. Используйте 'strlen'! Вероятно, это причина вашей проблемы, так как вы, вероятно, переписываете за пределы выделенной памяти и перезаписываете несвязанные данные. –

+0

26 байт в 6 блоков косвенно теряется в потере записи 1 из 9 в таНосе (vg_replace_malloc.c: 270) по: to_lower (driver.c: 24) полукокса * to_lower (символ * ули) { \t символа * new_str = malloc (strlen (str) +1); – user2266603

0

Вам необходимо каким-либо образом высвободить ItemType с после, вы закрываете токенизатор. Если вы освободите их раньше, токенизация будет считываться в освобожденную память, чего вы очень не хотите делать.

Я предполагаю, что ваш фреймворк должен обеспечить некоторый способ освобождения независимо от того, что подавалось в HM_Put. Если это не так, вам нужно сделать это самостоятельно.

Например (это может быть оптимизировано, решая которые, чтобы между маркерами и to_lower ред лексем):

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(); 
Смежные вопросы