1

Valgrind は、以前に malloc された構造体が解放されたときに、メモリ エラーが発生したことを常に指摘します。構造体は次のようになります。

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にアクセスできなくなります。一時変数に保存するだけです: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 に答える