В C: файл не найден Ошибка при повторном использовании функции readInputFile в fclose () - PullRequest
0 голосов
/ 15 января 2020

Я пытаюсь прочитать два разных файла .txt, чтобы сравнить их позже в моем коде. Для этого проекта мне нужно было динамически распределять файлы, так как мне не разрешен максимальный размер символов. Моя функция правильно получает информацию о файле правильно при первом запуске, но вылетает с ошибкой при втором запуске при чтении второго входного файла. Ошибка: Ошибка: Файл не найден. Любая идея о том, что вызывает его сбой во время второго запуска? Спасибо

int main(int argc, char *argv[])
{ 
    struct stat stringBuffer1; 
    struct stat stringBuffer2;
    stat(argv[1], &stringBuffer1); 
    stat(argv[2], &stringBuffer2); 
    FILE *textFile1 = NULL, *textFile2 = NULL, *outputFile = NULL; 
    textFile1=fopen(argv[1], "r");
    textFile2=fopen(argv[2], "r");
    char* fileString1;
    char* fileString2;
    printf("code before readInputFile");
    fileString1 = strdup(readInputFile(textFile1,stringBuffer1));
    fileString2 = strdup(readInputFile(textFile2,stringBuffer2));

char* readInputFile(FILE* targetFile, struct stat stringBuffer)
{       
    char *tempString=malloc(stringBuffer.st_size+1); 
    fread(tempString, 1, stringBuffer.st_size, targetFile); 
    fclose(targetFile); //Error happens here
    char* finalString = &tempString[stringBuffer.st_size];
    tempString[stringBuffer.st_size]=0; // Setting 0-Byte
    strcpy(finalString,tempString);
    free(tempString);
    return finalString;
}

1 Ответ

1 голос
/ 15 января 2020

У вас здесь неопределенное поведение, и все остальное, вероятно, нарушено им. Проблема в том, что:

char *tempString=malloc(stringBuffer.st_size+1); 

выделяет память,

char* finalString = &tempString[stringBuffer.st_size];

делает указатель (почти) на конец указанной памяти, затем:

strcpy(finalString,tempString);

и сам по себе не определен (strcpy требует, чтобы источник и назначение не перекрывались), и даже если он "работает", он записывает путь после конца указанной памяти (возможно, на неопределенный срок, так как он уносится завершающий байт NUL, который вы только что записали на первый скопированный байт). Чтобы добавить оскорбление к травме,

free(tempString);

освобождает то, на что фактически ссылается мало фактически выделенной памяти finalString, поэтому return возвращает указатель, который не может быть юридически разыменован (strdup является одновременно чтение из недопустимого указателя и вероятное выделение из поврежденной кучи).

Ошибка, которую вы видите, скорее всего, вызвана этим волевым взмахом кучи памяти, которой вы не владеете.

Если вы хотите, чтобы это работало, самый простой подход - вернуть malloc отредактированную память без free ее выделения, оставив ее до вызывающей стороны до free, когда они будут готовы. Вы не копируете данные (это уже там, где вы хотите, чтобы они были в конце концов):

char* readInputFile(FILE* targetFile, struct stat stringBuffer)
{       
    char *tempString=malloc(stringBuffer.st_size+1); 
    fread(tempString, 1, stringBuffer.st_size, targetFile);
    tempString[stringBuffer.st_size] = '\0';
    fclose(targetFile);
    return tempString;
}

Удалите оболочки strdup в вашем main (он уже получает динамически выделенную память обратно) и просто добавьте free(fileString1); и free(fileString2); к main после того, как вы закончите с возвращенными данными.

...