Valgrind 给出错误内存“仍然可达”

Big*_*101 1 c valgrind memory-leaks strdup

当我运行 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)
Run Code Online (Sandbox Code Playgroud)

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

Run Code Online (Sandbox Code Playgroud)

第 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;
        } 
Run Code Online (Sandbox Code Playgroud)

Mar*_*lli 6

您应该关心的 Valgrind 输出行是这一行:

==303912==    by 0x109B8E: main (minishell.c:178)
Run Code Online (Sandbox Code Playgroud)

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

Valgrind 标记为“仍然可达”的内存是:

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

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

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