C - fgets返回损坏的数据

时间:2017-04-29 19:23:57

标签: c pointers fgets

我正在编写一个应该读取文件并根据它执行某些操作的程序,但是我似乎在正确读取该行时遇到了问题。 我正在使用while函数:

static int readLineFromFile(char **destination, int *allocSize, FILE *file)
{
    char *newDest;
    if (fgets(*destination, (*allocSize) - 2, file))
    {
        int strend = strlen(*destination);
        while (*(*destination + strend - 1) != '\n')
        {
            printf("\"%s\"\n", *destination);
            size_t length = (*allocSize) * 2;  //WE ARE GOING TO ALLOCATE MORE MEMORY AND KEEP READING
            newDest = realloc(*destination, length);
            if (!newDest)
            {
                free(*destination);
                return 2; //2 - FAILED ALLOC
            }
            *destination = newDest;
            fgets(*destination + strend, (length / 2), file);
            *allocSize = length;
            strend = strlen(*destination);
        }
        *(*destination+strend-1) = '\0'; //WE DONT NEED THE \n AT THE END, SO WE JUST REPLACE IT WITH \0
        printf("D %s\n", *destination);
        return 0;
    }
    else{
        if (feof(file)) {   //IF NOTHING IS LEFT TO READ, WE CHECK IF IT IS BECAUSE OF EOF (1) OR AN ERROR (2)
            return 1;
        }
        return 2;
    }
}

其中** destination是指向字符串mallocated区域指针的指针,* allocSize指针用于**目标的大小,* file指向文件流。

然而,在第二次重新分配之后(所以,在我有两行比allocSize长并且必须重新分配之后,确切地说在多少行之后并不重要),printf-s(都在重新分配后循环和在realloc周期开始时)正确返回5个字符,之后返回4个字符(" ABCDE ????"而不是" ABCDEFGHIJK ...")。我认为这是因为strtok函数后来在while循环中(读完行后),但似乎没有。

然后我发现在代码的后面,我为我加载的行的解析子字符串分配了空间 - 如果我删除这部分代码,一切都可以正常工作(它甚至不重要,我分配了多少字节,我仍然不断受到损坏的字符串)。所以在这一点上,我甚至开始思考我是否以某种方式打破了操作系统。

所以,如果有人能告诉我,如果这个功能有错误,或者我应该在其他地方寻找它,那就太好了。感谢。

此外,以下是while循环中的其他代码: STRTOK,fileLine是readLine的*目的地:

char *strtokStart = malloc (strlen (fileLine)+2);
strcpy (strtokStart, fileLine);
char *strtokSave = fileLine;
strcpy (newKey, strtok_r (fileLine, "=", &strtokSave));
strcpy (newValue, strtok_r (NULL, "\n", &strtokSave));
free (strtokStart);

MALLOCATING其他字符串:

config->topKey->key = (const char *) malloc(strlen(newKey) + 1);
config->topKey->value = (const char *) malloc(strlen(newValue) + 1);
if (!(config->topKey->key && config->topKey->value))
{
    printf("ALLOC FAIL\n");
    statusVal = 1;
    break;
}

1 个答案:

答案 0 :(得分:0)

readLineFromFile有两个问题:

  1. 如果文件未以\ n结尾,则while循环会继续分配更多内存,直到realloc失败。检查第二个fgets的返回码确实检测到那种情况!
  2. 错误的realloc错误处理:free(* destination)使调用者返回错误的指针。最好免费删除。或者添加* destination = NULL。
  3. 否则readLineFromFile很好,应该使用有效的输入文件。如果没有无效的输入文件,代码中的其他地方可能会出现更多错误。

    当然,应该使用malloc的缓冲区调用readLineFromFile。