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

时间:2012-06-08 11:12:32

标签: c memory valgrind

当以前的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);即可免费获取结构。然而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);
      }
    }
  }
}

2 个答案:

答案 0 :(得分:5)

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

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

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

(另外,请记住在释放后将b设置为null,这样您就没有Dangling Pointer

答案 1 :(得分:0)

BULLET内的8个字节很可能是字段next。您可能已将&next保留在某处并在ctrl_bullets (player.c:89)中重复使用。但是既然你没有向我们展示这些代码,我们就不能多说了。

编辑:或者我们可能猜测你的next指针形成一个链表,而你没有将另一个元素的next指针设置为{{1在执行0