2

単純なプログラムからメモリリークを見つけようとしていました:

#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が true の場合、プログラムは free 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で、私のOSはmacOS Big Sur 11.5.2です

4

1 に答える 1