Valgrind …大小为8的块中的4个字节
尝试释放列表后,我在Valgrind中收到此错误。 print_list将列表转储到syslog。 我非常有信心输出是正确的。
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:
15 char *temp = malloc(10); 16 char *temp2 = malloc(10); 17 free(temp); 18 free(temp2); 19 m61_close_for_valgrind();
list.h
typedef struct lnode { ACTIVE_ALLOCATION *value; struct lnode *next; } lnode;
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 } }
系统日志
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
正如caf已经写过的那样,你正在访问刚刚被释放的内存。
要解决这个问题,不要使用双指针,单指针在这里会做得很好。
所以更换
lnode **nptr = &s->head;
通过
lnode *nptr = s->head;
同样的
lnode **tmp = nptr;
在循环。 做了
lnode *tmp = nptr;
当你在它的时候放下双重任务。
然后访问值和下一个
tmp->value
和
tmp->next
直
在除第一个之外的每个迭代中, tmp
指向前一个节点的next
指针 – 但是您已经释放了该节点(在上一次迭代中),因此tmp
指向一个已释放的块,并且您无法取消引用它。