C语言 Valgrind... 4 个字节在一个大小为 8 的块中 free'd

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18886298/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:28:30  来源:igfitidea点击:

Valgrind... 4 bytes inside a block of size 8 free'd

cvalgrind

提问by user994165

I'm getting this error in Valgrind after attempting to free a list. print_list dumps the list to the syslog. I'm pretty confident that output is correct.

尝试释放列表后,我在 Valgrind 中收到此错误。print_list 将列表转储到系统日志。我非常有信心输出是正确的。

Valgrind:

瓦尔格林:

==7028== 1 errors in context 1 of 10:
==7028== Invalid read of size 4
==7028==    at 0x8049603: free_list (list.c:239)
==7028==    by 0x80488B5: m61_close_for_valgrind (m61.c:36)
==7028==    by 0x8048825: main (mytest.c:19)
==7028==  Address 0x420006c is 4 bytes inside a block of size 8 free'd
==7028==    at 0x4028F0F: free (vg_replace_malloc.c:446)
==7028==    by 0x804960C: free_list (list.c:239)
==7028==    by 0x80488B5: m61_close_for_valgrind (m61.c:36)
==7028==    by 0x8048825: main (mytest.c:19)
==7028== 

mytest.c:

mytest.c:

15  char *temp = malloc(10);
16  char *temp2 = malloc(10);
17  free(temp);
18  free(temp2);
19  m61_close_for_valgrind();

list.h

列表.h

typedef struct lnode {
    ACTIVE_ALLOCATION *value;
    struct lnode *next;
} lnode;

list.c (Called by m61_close_for_valgrind()

list.c(由 m61_close_for_valgrind() 调用

void free_list(LIST *s) {

    lnode **nptr = &s->head;

    print_list(s);
    while (*nptr) {
        lnode **tmp = nptr;
        tmp = nptr;

        if ((*tmp)->value) {
            syslog(LOG_NOTICE,"Freeing (*tmp)->value=%p\n", (*tmp)->value);
            //printf("%p\n",(*nptr)->value);
            free((*tmp)->value);    //Free active allocation metadata
        }

        nptr = &(*nptr)->next;
        syslog(LOG_NOTICE,"New *nptr value=%p\n", (*nptr));

        syslog(LOG_NOTICE,"Freeing (*tmp)=%p\n", (*tmp));
        free(*tmp);             //Free node

    }

}

syslog

系统日志

Sep 19 00:37:02 appliance mytest[7759]:   -- Start List Dump --
Sep 19 00:37:02 appliance mytest[7759]:   (*nptr)=0x903f220 (*nptr)->value=0x903f208   (*nptr)->next=0x903f260  (*nptr)->value->ptr=0x903f1f0
Sep 19 00:37:02 appliance mytest[7759]: (*nptr)->value->ptr=0x903f1f0
Sep 19 00:37:02 appliance mytest[7759]:   (*nptr)=0x903f260 (*nptr)->value=0x903f248   (*nptr)->next=(nil)  (*nptr)->value->ptr=0x903f230
Sep 19 00:37:02 appliance mytest[7759]: (*nptr)->value->ptr=0x903f230
Sep 19 00:37:02 appliance mytest[7759]:   -- End List Dump --
Sep 19 00:37:02 appliance mytest[7759]: Freeing (*tmp)->value=0x903f208
Sep 19 00:37:02 appliance mytest[7759]: New *nptr value=0x903f260
Sep 19 00:37:02 appliance mytest[7759]: Freeing (*tmp)=0x903f220
Sep 19 00:37:02 appliance mytest[7759]: Freeing (*tmp)->value=0x903f248
Sep 19 00:37:02 appliance mytest[7759]: New *nptr value=(nil)
Sep 19 00:37:02 appliance mytest[7759]: Freeing (*tmp)=0x903f260

采纳答案by Bodo Thiesen

As caf already wrote, you're accessing memory that has just been freed.

正如 caf 已经写的那样,您正在访问刚刚被释放的内存。

To fix that, just don't use double pointers, single pointers will do very well here.

为了解决这个问题,不要使用双指针,单指针在这里会做得很好。

So replace

所以更换

lnode **nptr = &s->head;

by

经过

lnode *nptr = s->head;

Same for

同为

lnode **tmp = nptr;

in the loop. Make it

在循环。做了

lnode *tmp = nptr;

and drop the double assignment just when you at it.

并在您完成时放弃双重任务。

Then access value and next by

然后访问 value 和 next by

tmp->value

and

tmp->next

directly

直接地

回答by caf

In each iteration other than the first, tmppoints at the nextpointer from the previous node - but you've already freed that node (in the previous iteration), so tmppoints into a freed block and you can't dereference it.

在除第一次之外的每次迭代tmp中,都next指向前一个节点的指针 - 但您已经释放了该节点(在前一次迭代中),因此tmp指向一个已释放的块并且您不能取消引用它。