Valgrind:在C中释放链表时无效读取大小8

时间:2016-12-18 08:32:02

标签: c struct linked-list valgrind doubly-linked-list

我正在尝试释放链表,该链表由列表结构和多个节点结构组成。每个节点结构都附加一个字符串。

我的思维过程是,如果我从头开始并循环到给定列表的尾部,我释放每个节点中的字符串,然后释放节点。在释放每个字符串和节点后,我释放列表本身。

我需要释放字符串,因为我在程序中较早的另一个函数中使用了字符串的大小。

我的功能是:

void releaseTB (TB tb){
    if(tb != NULL){
        if(tb->head != NULL){
            Node curr = tb->head;
            Node prev = NULL;
            while(curr != NULL && curr != tb->tail->next){
                prev = curr;
                curr = curr->next;
                free(prev->line);
                free(prev);
            }
        }
        free(tb);
    }
}

当我只想在更大的列表中释放子列表时,while循环中的条件curr != tb->tail->next正在处理。

如果它完全不相关,这些是我的结构:

typedef struct textbuffer *TB;

typedef struct node *Node;

struct textbuffer{
    Node head;
    Node tail;
};

struct node{
    Node prev;
    Node next;
    char *line;
};

我在运行程序时得到正确的输出,但是我得到一个大小为8的无效读取。valgrind输出是:

==7705== Memcheck, a memory error detector
==7705== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7705== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==7705== Command: ./dry5
==7705== 
Original Tb:
1.1 abc
1.2 def
xxxxx

==7705== Invalid read of size 8
==7705==    at 0x400ADC: releaseTB (textbuffer.c:124)
==7705==    by 0x4013EF: deleteTB (textbuffer.c:355)
==7705==    by 0x4007FA: main (dry5.c:14)
==7705==  Address 0x51e0208 is 8 bytes inside a block of size 32 free'd
==7705==    at 0x4C29E90: free (vg_replace_malloc.c:473)
==7705==    by 0x400ACC: releaseTB (textbuffer.c:128)
==7705==    by 0x4013EF: deleteTB (textbuffer.c:355)
==7705==    by 0x4007FA: main (dry5.c:14)
==7705== 
First and second line are deleted...
xxxxx

Released Tb 
==7705== 
==7705== HEAP SUMMARY:
==7705==     in use at exit: 0 bytes in 0 blocks
==7705==   total heap usage: 11 allocs, 11 frees, 219 bytes allocated
==7705== 
==7705== All heap blocks were freed -- no leaks are possible
==7705== 
==7705== For counts of detected and suppressed errors, rerun with: -v
==7705== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

其中:releaseTB (textbuffer.c:124)while(curr != NULL && curr != tb->tail->next){0x400ACC: releaseTB (textbuffer.c:128)free(prev);

非常感谢任何帮助。如果需要进一步澄清,我会尽力解释。

1 个答案:

答案 0 :(得分:1)

在开始循环之前,tb->tail指向何处?

如果为NULL,则tb->tail->next错误。

如果它不是NULL,并且指向列表中的某个节点,那么在释放所有节点时它仍然是错误的。