1

当先前 malloc 的结构被释放时,Valgrind 总是抱怨存在内存错误。该结构如下所示:

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

...我通过使用分配内存

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

稍后,只需调用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);
      }
    }
  }
}
4

2 回答 2

5

问题是你释放了 b,然后尝试访问 b->next

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

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

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

于 2012-06-08T14:31:44.143 回答
0

里面的 8 个字节BULLET很可能是字段next。你可能已经保存在&next某个地方并在ctrl_bullets (player.c:89). 但是由于您没有向我们展示该代码,因此我们不能多说。

编辑:或者我们可以猜测您的指针next形成了一个链表,并且您在执行.next0free

于 2012-06-08T11:25:23.097 回答