Sau*_*oat 1 c valgrind memory-leaks
以下程序:
#include <stdlib.h>
int main(void)
{
    char *my_str = malloc(42 * sizeof(char));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译如下:
gcc -g -o prog prog.c
Run Code Online (Sandbox Code Playgroud)
并用 Valgrind 执行如下:
valgrind --leak-check=full ./prog
Run Code Online (Sandbox Code Playgroud)
产生以下(截断的)输出:
...
==18424== HEAP SUMMARY:
==18424==     in use at exit: 42 bytes in 1 blocks
==18424==   total heap usage: 1 allocs, 0 frees, 42 bytes allocated
==18424== 
==18424== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==18424==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18424==    by 0x10865B: main (main.c:5)
==18424== 
==18424== LEAK SUMMARY:
==18424==    definitely lost: 42 bytes in 1 blocks
==18424==    indirectly lost: 0 bytes in 0 blocks
==18424==      possibly lost: 0 bytes in 0 blocks
==18424==    still reachable: 0 bytes in 0 blocks
==18424==         suppressed: 0 bytes in 0 blocks
...
Run Code Online (Sandbox Code Playgroud)
为什么 Valgrind 说未释放的内存“肯定会丢失”?
这意味着找不到指向该块的指针。该块被归类为“丢失”,因为程序员不可能在程序退出时释放它,因为不存在指向它的指针。这可能是在程序的某个较早点丢失指针的症状。
但是,很明显我可以在程序退出之前轻松释放该块。我在这里缺少什么?内存不应该“仍然可以访问”吗?
这是“绝对丢失”与“仍然可达”的示例:
#include <stdio.h>
#include <stdlib.h>
void *p;
int main()
{
    p = malloc(10);
    p = malloc(100);
    void *m = malloc(50);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码中发生的事情如下:
p.p. 这会覆盖指向 10 个已分配字节的指针值,并且没有其他引用。所以那个记忆“肯定会丢失”。m.main返回导致生命周期m结束。因此,没有存储指向 50 字节的内存指针的引用,因此内存“肯定会丢失”。p,因此清理例程(例如 由atexit或其他编译器特定方法调用的那些例程)仍然可以清理该内存。所以它“仍然可以到达”。在此代码上运行 valgrind 时,它输出以下内容:
#include <stdio.h>
#include <stdlib.h>
void *p;
int main()
{
    p = malloc(10);
    p = malloc(100);
    void *m = malloc(50);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
这与上面的描述一致。
总而言之,如果指向它的指针存储在文件范围变量中或被任何“仍然可访问”的内存指向,则该内存是“仍可访问的”。否则就丢失了。