【问题标题】:VS2015: non accurate fread after a fseek operationVS2015:fseek 操作后 fread 不准确
【发布时间】:2017-05-02 07:34:15
【问题描述】:

在将项目从 vs2008 迁移到 vs2015 时,我陷入了看起来像是 VS2015 libc 中的错误。 问题是在对位置 X 执行 fseek 操作后,fread 从 X+10 开始读取数据。

没有引发错误,fseek 操作返回参与位置后的 ftell 调用,但 fread 未从参与位置开始。而且,它依赖于之前的 fseek/fread 操作。

使用 VS2008(32 或 64 位)运行时不会出现此问题,但使用 VS2015(32 或 64 位)运行时会出现此问题。

提前感谢您的任何想法!

二进制文件可用here。 示例代码:

#include <fstream>
#include <iostream>
#include <iomanip>
#include <windows.h>

bool foo(FILE *f, unsigned char *buffer, int seek_to, int read_bytes)
{
    size_t res = 0;
    std::cout << "\tSeek to " << seek_to << std::endl;
    // issue present if using fseek or _fseeki64
    if (fseek(f, seek_to, SEEK_SET) != 0)
    {
        std::cout << "\tFAILED" << std::endl;
        return false;
    }
    std::cout << "\tRead " << read_bytes << " bytes" << std::endl;
    if ((res = fread(buffer, 1, read_bytes, f)) != read_bytes)
    {
        std::cout << "\tFAILED, " << res << "bytes readen" << std::endl;
        return false;
    }
return true;
}

// issue is present in 32 and 64bits of VS2015 update 3
int main(int argc, char **argv)
{
    // open the AVC binary file
    FILE *favc = fopen(argv[1], "rb");    
    // big buffer
    unsigned char *buffer = new unsigned char[1024*1024];
    // step 1, seek and read
    std::cout << "Step 1" << std::endl;
    foo(favc, buffer, 35026374, 7730);
    std::cout << "Step 2" << std::endl;
    foo(favc, buffer, 35030470, 8192);
    // failing reading, buffer should start with 00 00 00 01 09
    std::cout << "Step 3 - where all failed" << std::endl;
    foo(favc, buffer, 35034577, 16428);
    std::cout << "Buffer: '";
    for (size_t i = 0; i < 5; ++i) std::cout << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)buffer[i];
    std::cout << "'" << std::endl;
    unsigned int v = *((unsigned int*)(buffer+1));
    if (v != 0x09010000) std::cout << "ISSUE DETECTED" << std::endl;
    return 0;
}

【问题讨论】:

  • 请注意: - 如果使用 fread_s/fopen_s 或 _open/_lseek/_read 函数,这也会出现
  • 如果使用 _open、_read 和 _lseek,则不存在问题。看起来就像 vs2015 上 fopen 中的缓冲错误
  • VS2017中也有....
  • 使用 setvbuf 调整缓冲区大小也会更改问题位置。似乎真的是缓冲的错误。
  • 在 Windows 10 上运行时不存在问题... :(

标签: visual-studio-2015 fread fseek


【解决方案1】:

问题已确认为 SDK8.1 目标上的 VC Redist 2015 的错误。 在此处查看错误跟踪:https://connect.microsoft.com/VisualStudio/feedback/details/3133357

和MSDN论坛状态:https://social.msdn.microsoft.com/Forums/en-US/8c4d27db-1128-4803-951b-fef515455a03/vs2015-non-accurate-fseekfread-operation?forum=msbuild&prof=required

解决方法是: - 不要使用 fopen/fread/fseek 函数,首选 WIN32 API CreateFile/... - 针对 Windows 10(不是带有 SDK8.1 的 7)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 2017-07-07
    • 2019-09-04
    • 2021-07-21
    • 2021-02-19
    相关资源
    最近更新 更多