我的析构函数中出现了双重释放错误。

4

我目前正在尝试从我的程序中释放所有东西,但一直遇到双重释放的问题。首先,我将展示我的构造函数:

table_t *table_construct (int table_size, int probe_type)
{
    int i;
    table_t *hash;
    if(table_size < 1) return NULL;

    hash = malloc(sizeof(table));
    hash->table = malloc(sizeof(list*) * table_size);
    for(i=0; i < table_size; i++)
    {
        hash->table[i] = (list *)malloc(sizeof(list));
        hash->table[i]->K = 0;
        hash->size++;
    }
    //hash->size = table_size;
    hash->probing_type = probe_type;
    hash->key_entries = 0;
    return hash;
}

我正在创建一个哈希表并分配了一个数组。在我的程序结束时,我使用这个析构函数:

void table_destruct (table *hash)
{
    int i;
    list *list, *temp;

    if(hash == NULL) return;

    for(i=0; i<hash->size; i++)
    {
        list = hash->table[i];
        while(list !=NULL)
        {
            temp = list;
            //list = list->next;
            free(temp);
        }
    }
    free(hash->table);
    free(hash);
} 

我遍历数组并释放所有我使用malloc分配的空间,然后删除整个数组。运行时出现以下错误:

*** glibc detected *** ./prog: double free or corruption (fasttop): 0x000000000223e2f0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f57f6086b96]
./prog[0x400bbf]
./prog[0x4032d0]
./prog[0x4014fb]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f57f602976d]
./prog[0x4009e9]
======= Memory map: ========
00400000-00406000 r-xp 00000000 08:01 272335                          
00606000-00607000 r--p 00006000 08:01 272335                             
00607000-00608000 rw-p 00007000 08:01 272335                             
0223e000-0225f000 rw-p 00000000 00:00 0                                  [heap]
7f57f5df2000-7f57f5e07000 r-xp 00000000 08:01 3411537                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f57f5e07000-7f57f6006000 ---p 00015000 08:01 3411537                    /lib/x86_64linux-gnu/libgcc_s.so.1
7f57f6006000-7f57f6007000 r--p 00014000 08:01 3411537                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f57f6007000-7f57f6008000 rw-p 00015000 08:01 3411537                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f57f6008000-7f57f61bd000 r-xp 00000000 08:01 3417211                    /lib/x86_64-linux-gnu/libc-2.15.so
7f57f61bd000-7f57f63bc000 ---p 001b5000 08:01 3417211                    /lib/x86_64-linux-gnu/libc-2.15.so
7f57f63bc000-7f57f63c0000 r--p 001b4000 08:01 3417211                    /lib/x86_64-linux-gnu/libc-2.15.so
7f57f63c0000-7f57f63c2000 rw-p 001b8000 08:01 3417211                    /lib/x86_64-linux-gnu/libc-2.15.so
7f57f63c2000-7f57f63c7000 rw-p 00000000 00:00 0 
7f57f63c7000-7f57f64c2000 r-xp 00000000 08:01 3417221                    /lib/x86_64-linux-gnu/libm-2.15.so
7f57f64c2000-7f57f66c1000 ---p 000fb000 08:01 3417221                    /lib/x86_64-linux-gnu/libm-2.15.so
7f57f66c1000-7f57f66c2000 r--p 000fa000 08:01 3417221                    /lib/x86_64-linux-gnu/libm-2.15.so
7f57f66c2000-7f57f66c3000 rw-p 000fb000 08:01 3417221                    /lib/x86_64-linux-gnu/libm-2.15.so
7f57f66c3000-7f57f66e5000 r-xp 00000000 08:01 3417227                    /lib/x86_64-linux-gnu/ld-2.15.so
7f57f68cf000-7f57f68d2000 rw-p 00000000 00:00 0 
7f57f68e1000-7f57f68e5000 rw-p 00000000 00:00 0 
7f57f68e5000-7f57f68e6000 r--p 00022000 08:01 3417227                    /lib/x86_64-linux-gnu/ld-2.15.so
7f57f68e6000-7f57f68e8000 rw-p 00023000 08:01 3417227                    /lib/x86_64-linux-gnu/ld-2.15.so
7fff79fe9000-7fff7a00a000 rw-p 00000000 00:00 0                          [stack]
7fff7a0e6000-7fff7a0e7000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)

我不知道我的问题出在哪里。有什么东西我没有看到吗?

我曾经在那里写过,但是因为看了一下之后,逻辑上对我来说没有意义,所以我将其注释掉了。我第一次就是正确的吗? - user081608
2
问题在于你根本不需要 while 循环。 - Mitch Wheat
我在使用它时遇到了相同的错误,而且在绘制出来后逻辑上也不合理,所以我将其注释掉了。 - user081608
对不起,但是你的意思是什么? - user081608
好的,去掉 while 循环解决了那个问题,非常感谢。 - user081608
2个回答

2

析构函数只需要是:

void table_destruct (table_t *hash)
{
    int i;

    if (hash == NULL) 
       return;

    for (i=0; i<hash->size; i++)
    {
        free(hash->table[i];);
    }
    free(hash->table);
    free(hash);
} 

0
for(i=0; i<hash->size; i++)
{
    list = hash->table[i];
    while(list !=NULL)
    {
        temp = list;
        //list = list->next;
        free(temp);
    }
}

您从未将 list = NULL 赋值,因此 while 条件仍然为 true,并且它再次进入循环以释放您刚刚 free'dlist


可能有点晚了?虽然是真的,但并不是答案。 - Mitch Wheat
@MitchWheat:哦...我以为这是双重释放的原因。你能解释一下这个概念吗?是因为OP赋值了“list = hash->table[i];”吗? - Abhineet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接