我很久没用过 C 了,显然我忘记的比我想象的要多。在尝试使用 malloc() 分配字符串时,我不断获取该字符串的旧数据,包括它的旧数据,当请求的空间较短时长度较长。这种情况确实包括指向被 free()'d 并设置为 NULL 的字符串的指针。这是我在终端中看到的示例运行:
yes, quit, or other            (<-message from program)
oooo                           (<-user input; this will be put to upper case and token'd)
------uIT LENGTH:4             (<-debug message showing length of userInputToken)
preC--tmp:                     (<-contents of tmp variable)
pstC--tmp:OOOO                 (<-contents of temp variable)
bad input                      (<-program response)
yes, quit, or other
yes
------uIT LENGTH:3
preC--tmp:OOOO                 (<-: tmp = malloc(sizeof(char)*(strlen(userInputToken)-1)); )
pstC--tmp:YESO                 (<-: strncpy(tmp,userInputToken,strlen(userInputToken)-1);  )
bad input
yes, quit, or other
yes
------uIT LENGTH:3
preC--tmp:YESO
pstC--tmp:YESO
bad input
yes, quit, or other
quit
------uIT LENGTH:4
preC--tmp:YESO
pstC--tmp:QUIT                 (<-: Successful quit because I only did 4 chars; if 5 were used, this would have failed)
如您所见, strlen(userInputToken) 获得了正确的长度,并用于获取正确数量的复制字符——但无论是 free() 还是 malloc() 似乎都不关心它。我无法弄清楚这里发生了什么!这是将 C 留给 Python 的惩罚吗?
更重要的是,应该清除 tmp 变量,而不管 free() 是什么,因为它受到其范围的限制。这是一切都失败的代码:
在 main.c 中:
void run() {
    outputFlagContainer *outputFlags = malloc(sizeof(outputFlagContainer));
    while(true) {
        puts("yes, quit, or other");
        outputFlags = getUserInput(outputFlags);
        if (outputFlags->YES) {
            puts("It was a yes!");
        } else if (outputFlags->QUIT) {
            break;
        } else {
            puts("bad input");
        }
    }
    free(outputFlags);
}
在 messageParserPieces.h 中:
outputFlagContainer *getUserInput(outputFlagContainer *outputFlags) {
    outputFlags = resetOutputFlags(outputFlags);
    char *userInput = NULL;
    char user_input[MAX_INPUT];
    char *userInputToken = NULL;
    char *tmp = NULL;
    char *finalCharacterCheck = NULL;
    // Tokens to search for:
    char QUIT[] = "QUIT";
    char YES[] = "YES";
    userInput = fgets(user_input, MAX_INPUT-1, stdin);
    int i = 0;
    while(userInput[i]) {
        userInput[i] = toupper(userInput[i]);
        i++;
    }
    userInputToken = strtok(userInput, " ");
    if (userInputToken) {
        finalCharacterCheck = strchr(userInputToken, '\n');
        if (finalCharacterCheck) {
            int MEOW = strlen(userInputToken)-1; // DEBUG LINE
            printf("\n------uIT LENGTH:%d\n", MEOW); // DEBUG LINE
            // The problem appears to happen here and under the circumstances that
            // userInput is (for example) 4 characters and then after getUserInput()
            // is called again, userInput is 3 characters long. 
            tmp = malloc(sizeof(char)*(strlen(userInputToken)-1));
            if (tmp == NULL) {
                exit(1);
            }
            printf("\npreC--tmp:%s\n", tmp); // This shows that the malloc DOES NOT use the given length.
            strncpy(tmp,userInputToken,strlen(userInputToken)-1);
            printf("\npstC--tmp:%s\n", tmp); // Copies in the correct number of characters.
            userInputToken = tmp;
            free(tmp);
            tmp = NULL;
        }
    }
    while (userInputToken != NULL) { // NULL = NO (more) tokens.
        if (0 == strcmp(userInputToken, YES)) {
            outputFlags->YES = true;
        } else if (0 == strcmp(userInputToken, QUIT)) {
            outputFlags->QUIT = true;
        }
        userInputToken = strtok(NULL, " ");
        if (userInputToken) {
            finalCharacterCheck = strchr(userInputToken, '\n');
            if (finalCharacterCheck) {
                tmp = malloc(sizeof(char)*(strlen(userInputToken)-1));
                if (tmp == NULL) {
                    exit(1);
                }
                strncpy(tmp,userInputToken,strlen(userInputToken)-1);
                userInputToken = tmp;
                free(tmp);
                tmp = NULL;
            }
        }
    }
    return outputFlags;
}
我假设这是某种明显的错误,但我今晚尝试用谷歌搜索它大约 2 小时。我想不出如何搜索这个不带 malloc() 教程的东西——我已经看过几个了。
任何见解都将不胜感激!