0

我在使用valgrind时遇到了写/读问题,我不明白为什么。错误始终发生在同一代码块上,仅更改内存地址。代码块是:

void stringModifier(char *string) {
    char *sourceString = string;
    char *destinyString = sourceString;

    while(*string != '\0') {
            *string = tolower(*string);

            if(*string != ' ') { *destinyString++ = *string; }

            string++;
    }

    *destinyString = '\0';
}

int qsortComparison(const void *a, const void *b) {
    return (*(char *)a - *(char *)b);
}

void qsortString(char *string, char *tempString) {
    strcpy(tempString, string);
    stringModifier(tempString);
    qsort(tempString, strlen(tempString), sizeof(char), qsortComparison);
}

void outputReader(char *string1, char *string2) {
    char *tempString1 = (char *) malloc (strlen(string1) * sizeof(char));
    char *tempString2 = (char *) malloc (strlen(string2) * sizeof(char));

    qsortString(string1, tempString1);
    qsortString(string2, tempString2);

    if(!strcmp(tempString1, tempString2)) { printf("V\n", string1, string2); }
    else { printf("F\n"); }
}

每次我使用outputReader并调用qsortString时,valgrind都会在strcpy发出写入错误警告,然后在stringModifier发出读取错误警告,发生在相同的内存地址上。

4

2 回答 2

1

您需要分配 strlen+1 来说明字符串的空终止符。

void outputReader(char *string1, char *string2) {
    char *tempString1 = (char *) malloc ((strlen(string1)+1) * sizeof(char));
    char *tempString2 = (char *) malloc ((strlen(string2)+1) * sizeof(char));
于 2013-08-27T12:55:38.990 回答
1

遵循相关调用之一的路径。

  1. char *tempString1 = (char *) malloc (strlen(string1) * sizeof(char));:这会分配一个字符串缓冲区,该缓冲区是string1 不包括0-terminator的字符数,如果要存储字符串的完整副本,则需要终止符的空间,但不分配它。

  2. qsortString(string1, tempString1);: 现在我们将源字符串缓冲区新分配的 one-char-too-short 缓冲区都传递给这个函数。

  3. 然后,qsortString()strcpy(tempString, string);: 这将向您不拥有的内存写入一个额外的字符(终止符)。因此这是未定义的行为

瓦林德是对的。你正在写(然后读)你不拥有的内存。分配应包括用于0终止符的空间。例如:malloc ((strlen(string1)+1) * sizeof(char));另一种选择,虽然不是 C 标准的一部分,但使用strdup(),它将为您正确处理分配复制。您选择如何处理我留给您的解决方案。

旁注:不要malloc()在 C 中强制转换返回值

于 2013-08-27T12:56:21.123 回答