Valgrind警告写入和读取错误

时间:2013-08-27 12:38:51

标签: c string valgrind

写入/读取 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 上的读取错误,发生在同一个内存地址上。

2 个答案:

答案 0 :(得分:1)

您需要将strlen + 1分配给字符串的null终止符。

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

答案 1 :(得分:1)

按照其中一个调用的路径进行操作。

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

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

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

  4. Valrind是对的。你正在写(然后阅读)你不拥有的记忆。分配应包括0 - 终结符的空间。例如:malloc ((strlen(string1)+1) * sizeof(char));另一个选项,虽然不是C标准的一部分,但是使用strdup(),它将正确处理分配复制。您如何选择接近我留给您的解决方案。

    旁注:Don't cast malloc() return values in C