【问题标题】:Valgrind gives error memory "still reachable"Valgrind 提供错误内存“仍然可以访问”
【发布时间】:2023-03-29 05:03:01
【问题描述】:

我在运行 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;
        } 

【问题讨论】:

  • 错误消息提到的第 42 行在 strdup.c 中,而不是在您的代码中。
  • by 0x109B8E: main (minishell.c:178) -- this 是您代码中的行。
  • free((char *)argvals[j]) 中的演员表应该是不必要的。如果不是char *argvals[j] 是什么?见minimal reproducible example
  • 没注意,谢谢!
  • argval 最初被标记为:char *argvals[4096];

标签: c memory-leaks valgrind strdup


【解决方案1】:

你应该关心的 Valgrind 输出行是这个特定的:

==303912==    by 0x109B8E: main (minishell.c:178)

它上面的其他行是指库函数中的代码,您无法控制这些代码。它们只是由 Valgrind 自动显示为堆栈跟踪的一部分。

被 Valgrind 标记为“仍可访问”的内存是:

  1. 在某个时候由您的程序分配。
  2. 程序退出前未释放。
  3. 在程序退出时仍被某个变量指向(这就是“可达”的意思)。

Valgrind 告诉您,您对strdup() 的调用分配了一些您从未释放的内存,但这不是真正的错误或问题。理论上free() 可以在从main 返回之前说内存,但这并不是真正需要的,因为操作系统会在退出时清除程序的整个内存空间。如果您需要分配一些内存直到程序结束,您可以避免“浪费时间”释放它。这就是为什么 Valgrind 会告诉你这件事,但实际上并没有将其报告为错误。

如果您在程序结束时才需要分配的内存,则应在不再需要时立即释放它。 Valgrind 无法真正知道是否是这种情况,但作为程序员,您需要了解它。

【讨论】:

    猜你喜欢
    • 2011-05-23
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多