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指向一个已释放的块,并且您无法取消引用它。