簡體   English   中英

Valgrind在嘗試釋放malloc的結構時報告內存錯誤

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

當釋放以前分配的結構時,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,這樣就不會有懸空指針了

next字段最有可能是BULLET內部的8個字節。 您可能已經將&next放在某個地方,並在ctrl_bullets (player.c:89)重復使用了。 但是由於您沒有向我們展示該代碼,所以我們不能多說。

編輯:也許我們可以猜測您的next指針形成了一個鏈表,並且在執行free時沒有將另一個元素的next指針設置為0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM