【问题标题】:Valgrind says "definitely leak" but is it?Valgrind 说“肯定会泄漏”,但真的是这样吗?
【发布时间】:2018-05-25 13:53:16
【问题描述】:

我正在尝试为井字游戏编写蒙特卡洛树搜索,但在运行时确实存在内存问题(例如我的计算机内存不足)。

所以我决定用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);
}

Playerplayer_t 的位置

typedef char player_t;
typedef struct player Player;
struct player {
    player_t symbol;
    unsigned score;
};

它们就是这样使用的;

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

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

Valgrind 转储;

==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)

其中Line 348player_init_all 的开始,Line 351player_init_allfor 循环的开始

【问题讨论】:

  • 你不是每个玩家做两个mallocs 吗? valgrind 正在标记的行中的一个被替换,但没有被释放

标签: c memory-leaks malloc valgrind free


【解决方案1】:

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

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

您在上述循环中为Player 对象分配内存。但紧接着player_init 将再次分配它并覆盖(*p)[0](*p)[1] 的值,肯定会泄漏您在上述循环中分配的内容。

【讨论】:

    【解决方案2】:

    看起来你 malloc 有足够的空间容纳你的 Players 数组:

    *p = (Player **) malloc (sizeof (Player *) * 2);
    

    然后malloc 3 Player 结构:

    (*p)[i] = (Player *) malloc (sizeof (Player));
    

    然后在你的init 函数中你malloc 再次Players

    *p = (Player *) malloc (sizeof (Player));
    

    这会覆盖最初的malloc,该malloc 已泄露,永远不会freed

    【讨论】:

      猜你喜欢
      • 2012-05-19
      • 1970-01-01
      • 2019-04-02
      • 1970-01-01
      • 2020-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多