Valgrind 给出错误记忆 "still reachable"
Valgrind gives error memory "still reachable"
我在 运行 Valgrind 时遇到以下错误,我试图释放所有使用的函数,但仍然有相同的错误消息
==303912== HEAP SUMMARY:
==303912== in use at exit: 348 bytes in 2 blocks
==303912== total heap usage: 1,192 allocs, 1,190 frees, 153,918 bytes allocated
==303912==
==303912== 348 bytes in 2 blocks are still reachable in loss record 1 of 1
==303912== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==303912== by 0x490050E: strdup (strdup.c:42)
==303912== by 0x109B8E: main (minishell.c:178)
==303912==
==303912== LEAK SUMMARY:
==303912== definitely lost: 0 bytes in 0 blocks
==303912== indirectly lost: 0 bytes in 0 blocks
==303912== possibly lost: 0 bytes in 0 blocks
**==303912== still reachable: 348 bytes in 2 blocks**
==303912== suppressed: 0 bytes in 0 blocks
==303912==
==303912== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
valgrind 错误消息中的第 42 行引用“signal_value = 1”,不知道为什么?!:
sigjmp_buf jmpbuf;
volatile sig_atomic_t signal_value= false;
void catch_signal(int sign) {
if (!signal_value) {
write(STDOUT_FILENO, "\n", 1);
siglongjmp(jmpbuf, 1);
signal_value = 1;
}
else{
signal_value = 0;
printf("\n");
}
}
这里的第 178 行就在“argvals[num_tokens] = strdup(token);”它在 valgrind
中引用的第二部分
while(token!=NULL) {
argvals[num_tokens] = strdup(token);
num_tokens++;
token = strtok(NULL, " ");
}
if (num_tokens == 0) {
continue;
} if (strcmp(argvals[0], "exit") == 0) {
for (int j = 0; j < num_tokens; j++) {
free((char*)argvals[j]);
}
return EXIT_SUCCESS;
}
您应该关心的 Valgrind 输出行是这一行:
==303912== by 0x109B8E: main (minishell.c:178)
它上面的其他行指的是库函数中的代码,您无法控制这些代码。它们只是由 Valgrind 自动显示为堆栈跟踪的一部分。
Valgrind 标记为“仍可访问”的内存是:
- 在某个时候由您的程序分配。
- 程序退出前未释放。
- 在程序退出时仍然被一些变量指向(这就是“可达”的意思)。
Valgrind 告诉您,您对 strdup()
的调用分配了一些您从未释放的内存,但这 不是 真正的错误或问题。理论上您可以 free()
在从 main
返回之前说内存,但实际上并不需要,因为操作系统将在退出时清除程序的整个内存 space。如果您需要分配一些内存直到程序结束,您可以避免“浪费时间”释放它。这就是为什么 Valgrind 会告诉您它,但实际上并没有将其报告为错误。
如果您直到程序结束才需要分配的内存,您应该在不再需要它时立即释放它。 Valgrind 不能真正知道是否是这种情况,这是你作为程序员的电话来理解它。
我在 运行 Valgrind 时遇到以下错误,我试图释放所有使用的函数,但仍然有相同的错误消息
==303912== HEAP SUMMARY:
==303912== in use at exit: 348 bytes in 2 blocks
==303912== total heap usage: 1,192 allocs, 1,190 frees, 153,918 bytes allocated
==303912==
==303912== 348 bytes in 2 blocks are still reachable in loss record 1 of 1
==303912== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==303912== by 0x490050E: strdup (strdup.c:42)
==303912== by 0x109B8E: main (minishell.c:178)
==303912==
==303912== LEAK SUMMARY:
==303912== definitely lost: 0 bytes in 0 blocks
==303912== indirectly lost: 0 bytes in 0 blocks
==303912== possibly lost: 0 bytes in 0 blocks
**==303912== still reachable: 348 bytes in 2 blocks**
==303912== suppressed: 0 bytes in 0 blocks
==303912==
==303912== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
valgrind 错误消息中的第 42 行引用“signal_value = 1”,不知道为什么?!:
sigjmp_buf jmpbuf;
volatile sig_atomic_t signal_value= false;
void catch_signal(int sign) {
if (!signal_value) {
write(STDOUT_FILENO, "\n", 1);
siglongjmp(jmpbuf, 1);
signal_value = 1;
}
else{
signal_value = 0;
printf("\n");
}
}
这里的第 178 行就在“argvals[num_tokens] = strdup(token);”它在 valgrind
中引用的第二部分 while(token!=NULL) {
argvals[num_tokens] = strdup(token);
num_tokens++;
token = strtok(NULL, " ");
}
if (num_tokens == 0) {
continue;
} if (strcmp(argvals[0], "exit") == 0) {
for (int j = 0; j < num_tokens; j++) {
free((char*)argvals[j]);
}
return EXIT_SUCCESS;
}
您应该关心的 Valgrind 输出行是这一行:
==303912== by 0x109B8E: main (minishell.c:178)
它上面的其他行指的是库函数中的代码,您无法控制这些代码。它们只是由 Valgrind 自动显示为堆栈跟踪的一部分。
Valgrind 标记为“仍可访问”的内存是:
- 在某个时候由您的程序分配。
- 程序退出前未释放。
- 在程序退出时仍然被一些变量指向(这就是“可达”的意思)。
Valgrind 告诉您,您对 strdup()
的调用分配了一些您从未释放的内存,但这 不是 真正的错误或问题。理论上您可以 free()
在从 main
返回之前说内存,但实际上并不需要,因为操作系统将在退出时清除程序的整个内存 space。如果您需要分配一些内存直到程序结束,您可以避免“浪费时间”释放它。这就是为什么 Valgrind 会告诉您它,但实际上并没有将其报告为错误。
如果您直到程序结束才需要分配的内存,您应该在不再需要它时立即释放它。 Valgrind 不能真正知道是否是这种情况,这是你作为程序员的电话来理解它。