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
Valgrind... 4 bytes inside a block of size 8 free'd
提问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指向一个已释放的块并且您不能取消引用它。

