在C:在fclose()上第二次使用readInputFile函数时找不到文件错误

问题描述 投票:0回答:1

我正在尝试读取两个不同的.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;
}
c linux file visual-studio-code dynamic-memory-allocation
1个回答
1
投票

您在这里有未定义的行为,其他所有可能都被它破坏了。问题是:

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

分配内存,

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

[指向(几乎)该内存末尾的指针,然后:

strcpy(finalString,tempString);

本身并没有定义(strcpy要求源和目标不重叠),即使它“起作用”,它也会在存储器的末尾写入way(可能无限期,因为它会消失)您刚刚在复制的第一个字节上写入的NUL终止字节)。要增加侮辱的伤害,

free(tempString);

释放实际上很少分配的有效内存finalString实际指向的,因此return返回的指针不能合法地取消引用(strdup既从无效的指针中读取,又可能从损坏的堆中分配)。

您所看到的错误可能是由于您不拥有的堆内存上的这种轻率的重踩造成的。

[如果您希望这样做,最简单的方法是不带malloc的情况下返回free ed的内存,完成后将其留给调用方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

© www.soinside.com 2019 - 2024. All rights reserved.