C中的免费链接列表

时间:2014-12-12 00:39:42

标签: c memory-leaks malloc

这是结构。

struct webPage{
  struct wordOccurance *rootWord;
  char URL[..];
};

struct wordOccurance{
  struct wordOccurance *nextWord;
  char word[...];
};

//Crawl and populate all words...
struct webPage *hopPage(url...){
   [scan all words in the web page]
   insertBackOfList(malloc(sizeof(struct wordOccurance)).. word)
}

//Now free..

void destroyPage(struct webPage *target){
    while(target != NULL){
        struct webPage *temp = target->next;
        destroyWords(target->rootWord);
        free(target);
        target = temp;
    }
}

void destroyWords(struct wordOccurance *target){
    while(target != NULL){
        struct wordOccurance *temp = target->nextWord;
        free(temp);
        target = temp;
    }
}

==20169== Invalid read of size 4
==20169==    at 0x8048DD5: destroyWords (index.c:109)
==20169==    by 0x80492E2: destroyPage (crawler.c:166)
==20169==    by 0x8049797: main (webSearch.c:91)
==20169==  Address 0x41d5298 is 0 bytes inside a block of size 1,008 free'd
==20169==    at 0x4024B3A: free (vg_replace_malloc.c:366)
==20169==    by 0x8048DE4: destroyWords (index.c:110)
==20169==    by 0x80492E2: destroyPage (crawler.c:166)
==20169==    by 0x8049797: main (webSearch.c:91)
==20169== 
==20169== Conditional jump or move depends on uninitialised value(s)
==20169==    at 0x8049781: main (webSearch.c:90)
==20169== 
==20169== 
==20169== HEAP SUMMARY:
==20169==     in use at exit: 52,432 bytes in 52 blocks
==20169==   total heap usage: 95 allocs, 43 frees, 82,392 bytes allocated
==20169== 
==20169== 1,008 bytes in 1 blocks are definitely lost in loss record 2 of 8
==20169==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
==20169==    by 0x8048A7F: indexPage (index.c:26)
==20169==    by 0x8048F1D: hopURL (crawler.c:46)
==20169==    by 0x8049570: main (webSearch.c:52)
==20169== 
==20169== 1,008 bytes in 1 blocks are definitely lost in loss record 3 of 8
==20169==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
==20169==    by 0x8048A7F: indexPage (index.c:26)
==20169==    by 0x80490E7: insertBack (crawler.c:108)
==20169==    by 0x8048FAB: hopURL (crawler.c:66)
==20169==    by 0x8049570: main (webSearch.c:52)
==20169== 
==20169== 50,416 (1,012 direct, 49,404 indirect) bytes in 1 blocks are definitely lost in loss record 8 of 8
==20169==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
==20169==    by 0x8048E8F: hopURL (crawler.c:28)
==20169==    by 0x8049570: main (webSearch.c:52)
==20169== 
==20169== LEAK SUMMARY:
==20169==    definitely lost: 3,028 bytes in 3 blocks
==20169==    indirectly lost: 49,404 bytes in 49 blocks
==20169==      possibly lost: 0 bytes in 0 blocks
==20169==    still reachable: 0 bytes in 0 blocks
==20169==         suppressed: 0 bytes in 0 blocks
==20169== 
==20169== For counts of detected and suppressed errors, rerun with: -v
==20169== Use --track-origins=yes to see where uninitialised values come from
==20169== ERROR SUMMARY: 356 errors from 13 contexts (suppressed: 14 from 7)

2 个答案:

答案 0 :(得分:2)

来自destroyPage()destroyWords()

    free(temp);
    target = temp;

您正在将一个变量设置为刚刚释放的指针。这永远不正确。

释放单链表的正确逻辑顺序通常是:

while (ptr) {
    oldPtr = ptr;
    ptr = ptr->next;
    free(oldPtr);
}

答案 1 :(得分:1)

为什么在刚刚释放temp后设置target = temp?

删除该行,然后执行:

struct wordOccurrence *temp;
while (target != NULL) {
    temp = target;
    target = target->nextWord;
    free(temp);
    temp = NULL; <-- optional
}

你的while循环是将目标设置为已经释放的节点,而在我的摘录中,temp会在每次迭代后重置为下一个目标节点,然后随后被释放。