Valgrind说"绝对泄漏"但是它呢?

ber*_*ran 0 c malloc free valgrind memory-leaks

我正在尝试编写一个用于井字游戏的蒙特卡罗树搜索,但是在运行它时会出现真正的内存问题(例如我的计算机内存不足).

所以我决定调查情况valgrind.

下面是一个代码块,上面valgrind写着"绝对泄漏".

void player_init (Player **p, player_t symbol)
{
  *p = (Player *) malloc (sizeof (Player));
  (**p).symbol = symbol;
  (**p).score = 0;
}

void player_init_all (Player ***p)
{
  *p = (Player **) malloc (sizeof (Player *) * 2);
  for (int i = 0; i < 2; i++)
    {
      (*p)[i] = (Player *) malloc (sizeof (Player));
    }
  player_init (&(*p)[0], PLAYER1);
  player_init (&(*p)[1], PLAYER2);
}

void player_destroy (Player *p)
{
  free (p);
}
Run Code Online (Sandbox Code Playgroud)

在哪里Playerplayer_t

typedef char player_t;
typedef struct player Player;
struct player {
    player_t symbol;
    unsigned score;
};
Run Code Online (Sandbox Code Playgroud)

它们以这种方式使用;

int main (int argc, char** argv)
{
    Player **players;
    player_init_all (&players);

    // OTHER FANCY CODE HERE

    for (int i = 0; i < 2; i++)
      player_destroy (players[i]);

    free (players);
    free (board);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我是以错误的方式传递指针吗?

Valgrind Dump;

==21657== 16 bytes in 1 blocks are definitely lost in loss record 1 of 15
==21657==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21657==    by 0x40147D: player_init_all (main.c:348)
==21657==    by 0x401698: main (main.c:426)
==21657== 
==21657== 16 bytes in 2 blocks are definitely lost in loss record 2 of 15
==21657==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21657==    by 0x4014AF: player_init_all (main.c:351)
==21657==    by 0x401698: main (main.c:426)
Run Code Online (Sandbox Code Playgroud)

在哪里Line 348是循环的开始player_init_allLine 351开始forplayer_init_all

AnT*_*AnT 6

这里有一个相当明显的内存泄漏

void player_init_all (Player ***p)
{
  *p = (Player **) malloc (sizeof (Player *) * 2);
  for (int i = 0; i < 2; i++)
    {
      (*p)[i] = (Player *) malloc (sizeof (Player));
    }
  player_init (&(*p)[0], PLAYER1);
  player_init (&(*p)[1], PLAYER2);
}
Run Code Online (Sandbox Code Playgroud)

您为Player上述循环内的对象分配内存.但是在那之后player_init会立即重新分配它并覆盖和的值,(*p)[0]并且(*p)[1]肯定会泄漏你在上面循环中分配的内容.