简体   繁体   English

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

[英]Valgrind reports a memory error when trying to free a malloc'ed struct

Valgrind always nags that there is a memory error when a previously malloc'ed struct is free'd. 当释放以前分配的结构时,Valgrind总是抱怨存在内存错误。 The struct looks as follows: 该结构如下所示:

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

... and I allocate the memory by using ...我通过使用分配内存

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

and later on, the struct is free'd by simply calling free(b); 然后,通过简单地调用free(b);释放结构free(b); . Valgrind however doesn't seem to be satisfied by this, and so it tells me 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)

Of course I can't just allocate only 8 bytes, because that would be the size needed to store the pointer, and not the size of the struct - so why does Valgrind keep telling me that there is an error? 当然,我不能只分配8个字节,因为那将是存储指针所需的大小,而不是结构的大小-那么为什么Valgrind总是告诉我有错误?

Edit : Some more code which could be relevant ... 编辑 :更多可能与之相关的代码...

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);
      }
    }
  }
}

The problem is that you free b, but then try to access b->next 问题是您释放了b,但是尝试访问b-> next

The error that valgrind tells you is that you are accessing an 8 byte block (the NEXT pointer) inside a 16 byte block that has been free'd. valgrind告诉您的错误是您正在访问已释放的16字节块中的8字节块(NEXT指针)。

If you free b, you can't access to b->next. 如果释放b,则无法访问b-> next。 Just store it in a tmp variable :P 只需将其存储在tmp变量中即可:P

(also, remember to set b to null after freeing it so you don't have a Dangling Pointer ) (此外,请记住在释放b之后将其设置为null,这样就不会有悬空指针了

8 bytes inside BULLET is most likely the field next . next字段最有可能是BULLET内部的8个字节。 You probably have kept &next somewhere and reuse that in ctrl_bullets (player.c:89) . 您可能已经将&next放在某个地方,并在ctrl_bullets (player.c:89)重复使用了。 But since you don't show us that code, we can't say much more. 但是由于您没有向我们展示该代码,所以我们不能多说。

Edit: or perhaps we can guess that your next pointer forms a linked list and that you haven't set the next pointer of another element to 0 when doing the free . 编辑:也许我们可以猜测您的next指针形成了一个链表,并且在执行free时没有将另一个元素的next指针设置为0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM