在IDE外运行时出现std::ifstream问题
std::ifstream issue when running outside of IDE
我有一个在Visual Studio调试环境中运行时工作良好的函数(带有调试和发布配置),但是当在IDE的外部运行应用程序时,就像最终用户会做的那样,程序崩溃了。这在Debug和Release版本中都会发生。
我知道调试和发布配置(优化,调试符号等)之间可能存在的差异,至少在某种程度上知道在Visual Studio内部运行应用程序与在它外部运行应用程序(调试堆,工作目录等)之间的差异。我看过其中的一些东西,但似乎没有一个能解决这个问题。这实际上是我第一次张贴到SO;通常我可以从现有的帖子中找到解决方案,所以我真的被难住了!
我能够附加一个调试器,奇怪的是,我得到两个不同的错误信息,基于我是否在Windows 7和Windows 8.1上运行应用程序。对于Windows 7,这个错误只是一个访问冲突,它在返回语句时就中断了。对于Windows 8.1,这是一个堆损坏错误,它在std::ifstream的构造上中断。在这两种情况下,所有的局部变量都被正确填充,所以我知道这不是函数无法找到文件或将其内容读入缓冲区data的问题。
同样有趣的是,这个问题在Windows 8.1上发生的几率只有20%,在Windows 7上发生的几率是100%,尽管这可能与这两个操作系统运行在不同的硬件上有关。
我不确定它有什么区别,但项目类型是Win32桌面应用程序,它初始化DirectX 11。你会注意到文件类型被解释为二进制,这是正确的,因为这个函数主要是加载编译过的着色器。
静态成员函数LoadFile:
HRESULT MyClass::LoadFile(_In_ const CHAR* filename, _Out_ BYTE** data, _Out_ SIZE_T* length)
{
CHAR pwd[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, pwd);
std::string fullFilePath = std::string(pwd) + "\" + filename;
std::ifstream file(fullFilePath, std::ifstream::binary);
if (file)
{
file.seekg(0, file.end);
*length = (SIZE_T)file.tellg();
file.seekg(0, file.beg);
*data = new BYTE[*length];
file.read(reinterpret_cast<CHAR*>(*data), *length);
if (file) return S_OK;
}
return E_FAIL;
}
更新:
有趣的是,如果我在堆上分配std::ifstream 文件而不删除它,问题就会消失。在我的例子中,一定是ifstream的销毁引起了问题。-
你不检查GetCurrentDirectoryA的返回值-也许你的当前目录名称太长或什么?
-
如果您已经使用Win32(不可移植!),使用GetFileSize来获取文件大小,而不是执行seek
-
更好的是,使用boost来编写可移植代码
-
打开编译器选项中的所有警告
-
启用ios异常
好吧,我放弃了尝试使用ifstream。显然,我不是唯一一个有这个问题的人……搜索"ifstream destructor crash"
因为这个应用程序是基于DirectX的,只会在Windows上运行,我去了Windows API路线,一切都工作得很好。
工作代码,以防有人关心:
HRESULT MyClass::LoadFile(_In_ const CHAR* filename, _Out_ BYTE** data, _Out_ SIZE_T* length)
{
CHAR pwd[MAX_PATH];
GetCurrentDirectoryA(MAX_PATH, pwd);
string fullFilePath = string(pwd) + "\" + filename;
WIN32_FIND_DATAA fileData;
HANDLE file = FindFirstFileA(fullFilePath.c_str(), &fileData);
if (file == INVALID_HANDLE_VALUE) return E_FAIL;
file = CreateFileA(fullFilePath.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (file == INVALID_HANDLE_VALUE) return E_FAIL;
*length = (SIZE_T)fileData.nFileSizeLow;
*data = new BYTE[*length];
DWORD bytesRead;
if (ReadFile(file, *data, *length, &bytesRead, NULL) == FALSE || bytesRead != *length)
{
delete[] *data;
*length = 0;
CloseHandle(file);
return E_FAIL;
}
CloseHandle(file);
return S_OK;
}
- std::ifstream::read 不会读取所有 512 字节,并设置 EOF 和失败位
- std::ifstream 在读取文件中最后一项时设置 eofbit,但仅在读取数值类型时发生
- 如何将QByteArray转换为std::istream或std::ifstream?
- 从带有 std::ifstream::read() 的文件中读取 int 遍历 char * 二进制数据
- std::ifstream因某种原因关闭了?
- 自定义类对象的C++向量 - 复制构造函数已删除 - std::ifstream
- std::ifstream 数据类型?
- std::ifstream,使用已删除功能
- std::ifstream 在二进制模式下,语言环境在 C++ 中
- std :: ifstream的开头角色是什么
- 如何从文件*中获取和std :: ifstream对象
- 如何使用行位置在std :: ifstream中导航
- 如何重用包含 std::ifstream 的类
- std::ifstream 将文件读取为 BYTE(无符号字符)而不是字符
- 使用 std::ifstream 读取 ASCII 文本文件C++
- 是否有任何模拟框架可以模拟std :: ifstream和其他I/O库
- Typo:bool to int conversion诱导的std :: ifstream在Linux下的错误
- std::ifstream 和读取文件
- std::ios::binary 或 std::ifstream::binary 和类似
- C++:使用std::ifstream读取二进制文件后删除缓冲区/指针时发生访问冲突