【发布时间】:2015-10-03 09:27:20
【问题描述】:
我有一个在 Visual Studio 调试环境中运行时可以正常工作的函数(同时使用 Debug 和 Release 配置),但在 IDE 的外部运行应用程序时,只是作为结束-用户会这样做,程序崩溃。 Debug 和 Release 版本都会发生这种情况。
我知道调试和发布配置(优化、调试符号等)之间可能存在的差异,并且至少在一定程度上意识到在 Visual Studio 内部运行应用程序与在其外部运行应用程序(调试堆、工作目录等)。我已经查看了其中的一些内容,但似乎都没有解决这个问题。这实际上是我第一次在 SO 上发帖;通常我可以从现有帖子中找到解决方案,所以我真的很难过!
我能够附加一个调试器,但奇怪的是,我收到了两条不同的错误消息,这取决于我是在 Windows 7 上还是在 Windows 8.1 上运行应用程序。对于 Windows 7,错误只是访问冲突,它在 return 语句上中断。对于 Windows 8.1,这是一个堆损坏错误,它在 std::ifstream 的构造上中断。在这两种情况下,所有局部变量都正确填充,所以我知道这不是函数无法找到文件或将其内容读入缓冲区 data 的问题。
另外有趣的是,在 Windows 8.1 和 100% 的情况下,该问题仅在大约 20% 的情况下发生在 Windows 7 上,尽管这可能与这些操作系统运行的硬件完全不同有关。
我不确定这有什么区别,但项目类型是 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 file 并且不删除它,问题就会消失。在我的情况下,ifstream 的破坏肯定是有问题的。
【问题讨论】:
-
删除古老的函数签名。您可以改用
std::vector<unit8_t> LoadFile(const char* filename)来消除新/删除和 nullptr 输出参数问题(顺便说一句:我猜 Out 是无效的) -
感谢@DieterLücking。尚未完成的唯一原因是,尽管有函数名称,但它实际上仅用于将编译后的着色器加载到具有两个 Out 类型成员的结构中参数,所以它只是让它现在更方便一点。尽管如此,该功能本质上是通用的,它可能应该按照您的建议进行更改或重命名为 LoadShader。 :)
标签: c++ debugging visual-studio-2012 visual-c++ iostream