Valgrind 说 "definitely leak" 是吗?
Valgrind says "definitely leak" but is it?
我正在尝试为井字游戏编写 Monte Carlo 树搜索,但在 运行 时确实存在内存问题(例如,我的计算机内存不足)。
所以我决定调查 valgrind
的情况。
下面,valgrind
说的代码块之一'definitely leak'。
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);
}
其中 Player
和 player_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 348
是 player_init_all
的开始,Line 351
是 player_init_all
中 for
循环的开始
这里有一个相当明显的内存泄漏
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]
的值,肯定会泄漏你在上面循环中分配的内容。
看起来你 malloc
足够 space 用于你的 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
,它会被泄露并且永远不会 freed
我正在尝试为井字游戏编写 Monte Carlo 树搜索,但在 运行 时确实存在内存问题(例如,我的计算机内存不足)。
所以我决定调查 valgrind
的情况。
下面,valgrind
说的代码块之一'definitely leak'。
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);
}
其中 Player
和 player_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 348
是 player_init_all
的开始,Line 351
是 player_init_all
for
循环的开始
这里有一个相当明显的内存泄漏
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]
的值,肯定会泄漏你在上面循环中分配的内容。
看起来你 malloc
足够 space 用于你的 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
,它会被泄露并且永远不会 freed