GCC 8.2.0在使用-fsanitize=address
编译的以下代码中未检测到泄漏:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
char *str1 = "tok1:val2";
char *str1_dup = strndup(str1, strlen(str1));
char *str1_dup_head = str1_dup;
char *tok1 = strsep(&str1_dup, ":");
// What should be done to avoid the memory leak
//free(str1_dup_head);
return 0;
}
但是,在以下情况下会检测到泄漏:
-fsanitize=leak
clang -fsanitize=address
strsep()
(str1_dup_cpy
)头上的副本(请参见下面的代码)#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
char *str1 = "tok1:val2";
char *str1_dup = strndup(str1, strlen(str1));
//char *str1_dup_head = str1_dup;
char *tok1 = strsep(&str1_dup, ":");
// What should be done to avoid the memory leak
//free(str1_dup_head);
return 0;
}
任何想法为什么会这样? -fsanitize=address
是否应该检测到它?
答案 0 :(得分:1)
LeakSanitizer通过设计使用非常原始的算法进行泄漏检测。每当对分配的块的引用恰好位于堆栈,寄存器或活动堆块中的某个位置时,LSan都会认为它是“可到达的”,因此不会报告泄漏。这使得它对编译器版本,优化选项(即变量是否溢出到堆栈等)非常敏感。我强烈怀疑您遇到此限制。