Valgrind在尝试释放malloc’ed结构时报告内存错误

当前一个malloc’ed结构被释放时,Valgrind总是唠叨存在内存错误。 结构如下所示:

typedef struct bullet { int x, y; struct bullet * next; } BULLET; 

…我通过使用分配内存

 BULLET * b; b = malloc(sizeof(BULLET)); // sizeof(BULLET) is 16 

然后,通过简单地调用free(b); ,结构是free(b); 。 然而Valgrind似乎并不满足于此,所以它告诉我

 ==2619== Invalid read of size 8 ==2619== at 0x40249F: ctrl_bullets (player.c:89) ==2619== by 0x405083: loop_game (game.c:305) ==2619== by 0x406CCA: main (main.c:47) ==2619== Address 0x5b8d818 is 8 bytes inside a block of size 16 free'd ==2619== at 0x4C29A9E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==2619== by 0x402E04: rm_bullet (player.c:329) ==2619== by 0x402485: ctrl_bullets (player.c:95) ==2619== by 0x405083: loop_game (game.c:305) ==2619== by 0x406CCA: main (main.c:47) 

当然我不能只分配8个字节,因为这将是存储指针所需的大小,而不是结构的大小 – 那么为什么Valgrind一直告诉我有错误?

编辑 :一些可能相关的代码……

 void ctrl_bullets(WINDOW * w_field, BULLETLIST * lb) { if (lb->num > 0) { BULLET * b; for (b = lb->head; b != NULL; b = b->next) // player.c:89 { if (b->x > CON_FIELDMAXX) { write_log(LOG_DEBUG, "Bullet %p is outside the playing field; x: %d; " "y: %d\n", (void *) b, b->x, b->y); rm_bullet(w_field, lb, b); } else { mv_bullet(w_field, b); } } } } 

问题是你释放b,但接着尝试访问b-> next

valgrind告诉您的错误是您正在访问已释放的16字节块内的8字节块(NEXT指针)。

如果您释放b,则无法访问b-> next。 只需将其存储在tmp变量中:P

(另外,记得在释放后将b设置为null,这样你就没有悬空指针 )

BULLET 8个字节很可能是next字段。 你可能已经保留了&next地方并在ctrl_bullets (player.c:89)重用它。 但既然你没有向我们展示这些代码,我们就不能多说了。

编辑:或许我们可以猜测你的next指针形成一个链表,并且在执行free时你还没有将另一个元素的next指针设置为0