c++ fread crash

fread crash 查找

windows11系统上


    char* buff = NULL;
    std::FILE* file;
    std::string hashValue = "";
    do {
        buff = (char*)malloc(1024);
        if (!buff) {
            printf("malloc memory failed");
            break;
        }
        file = std::fopen(filePath, "rb");
        if (!file) {
            printf("open file failed %s", filePath);
            break;
        }
        size_t len, result;
        while (1) {
            if ((len = std::fread(buff, sizeof(char), 1024, file)) <= 0) {
                break;
            }
            hasher.add(&buff[0], len);
            if ((result = std::fseek(file, 0, SEEK_CUR)) !=
                0) {
                break;
            }
        }

fread crash 有老哥帮忙看看是什么问题

在上述代码中,fread 函数的调用可能会导致程序崩溃的原因有以下几种可能:

  1. 内存分配问题:在每次循环开始时,您都会分配一块 1024 字节的内存。如果内存分配失败,malloc 函数会返回 NULL,并且您没有检查 buff 是否为 NULL,就直接使用了 buff 指针,这将导致访问无效内存的错误。因此,您需要在每次分配内存后检查 buff 是否为 NULL,如果是,则应该释放之前分配的内存(如果存在),并退出循环。

  2. 文件读取问题:在读取文件时,您没有检查读取的字节数是否与预期的字节数相同。如果因为文件结尾或者其他原因导致读取的字节数小于预期值,可能会导致 hasher.add 函数访问无效内存,从而引发程序崩溃。因此,您需要在每次读取文件后检查实际读取的字节数,如果小于预期值,则应该退出循环。

  3. 文件操作问题:在每次循环中,您都会调用 fseek 函数,该函数将当前文件位置设置为相对于当前位置的偏移量。如果 fseek 函数调用失败,可能会导致后续的文件读写操作出错。因此,您需要在每次调用 fseek 后检查返回值是否为 0,如果不是,则应该退出循环。

综上所述,建议您在代码中添加适当的错误处理代码,以确保程序能够正确地处理各种异常情况。同时,建议您使用 C++ 标准库中的 RAII 技术来管理内存和文件句柄,以避免手动管理内存和文件句柄时出现的问题。

这段代码存在一个可能导致 crash 的Bug。问题出在调用fread后,可能会导致buff中的数据变化。但在后续的hasher.add()中仍然使用buff[]。

fread(buff, sizeof(char), 1024, file);  // buff可能会被修改
hasher.add(&buff[0], len); // 此时使用buff已失效

fread读取文件数据可能会修改buff的内容,覆盖之前的值。
但此时仍然使用buff的地址调用hasher.add(),导致未知的错误。

修改后的代码

char temp[1024];
fread(temp, sizeof(char), 1024, file);  
hasher.add(&temp[0], len);  

// 使用临时缓冲区读取文件,再传入hasher