我试图从一个简单的程序中找到内存泄漏:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
void parse(const char* input) {
// Goal: parse out a string between brackets
// (e.g. " [target string]" -> "target string")
char *mutable_copy = strdup(input);
// Find open bracket
char *open_bracket = strchr(mutable_copy, '[');
if (open_bracket == NULL) {
printf("Malformed input!\n");
free(mutable_copy);
return;
}
// Make the output string start after the open bracket
char *parsed = open_bracket + 1;
// Make sure there is at least one character in brackets
if (parsed[0] == '\0') {
printf("There should be at least one character in brackets!\n");
free(mutable_copy);
return;
}
// Find the close bracket
char *close_bracket = strchr(parsed, ']');
if (close_bracket == NULL) {
printf("Malformed input!\n");
return;
}
// Replace the close bracket with a null terminator to end the parsed
// string there
*close_bracket = '\0';
printf("Parsed string: %s\n", parsed);
free(mutable_copy);
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <string to parse>\n", argv[0]);
return 1;
}
parse(argv[1]);
return 0;
}
使用以下命令:
clang -g -O0 -Wall -Wextra -std=gnu99 -fsanitize=address,leak -o 3-bracket-parser 3-bracket-parser.c
很明显,在这个程序中,如果close_bracket == NULL
为真,那么程序返回时没有空闲的mutable_copy,所以存在内存泄漏。
但是,当我运行此命令时,它不会报告任何错误,并且我的消毒剂也没有输出。我只启用了泄漏消毒剂再次尝试,这次它起作用了:
=================================================================
==19699==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 17 byte(s) in 1 object(s) allocated from:
#0 0x10f77ab48 in wrap_malloc+0x58 (libclang_rt.lsan_osx_dynamic.dylib:x86_64h+0x9b48)
#1 0x7fff202b88d1 in strdup+0x1f (libsystem_c.dylib:x86_64+0x578d1)
#2 0x10f763db4 in parse 3-bracket-parser.c:10
#3 0x10f763edd in main 3-bracket-parser.c:51
#4 0x7fff203a7f3c in start+0x0 (libdyld.dylib:x86_64+0x15f3c)
SUMMARY: LeakSanitizer: 17 byte(s) leaked in 1 allocation(s).
我想知道为什么在启用其他消毒剂时泄漏消毒剂不起作用。
我的 clang 版本是 Homebrew clang 版本 12.0.1,我的操作系统是 macOS Big Sur 11.5.2