1

例外提到

FILE* __cdecl _getstream

我打电话fopen,它一直在崩溃。

AfxMessageBox("getting here 1");
FILE* filePtr = fopen(fileName, "rb");
AfxMessageBox("getting here 2");

出于某种原因,我从来没有到达过第二个消息框。有趣的是,当我处于调试模式时,该应用程序运行良好。为什么?

4

4 回答 4

2

我认为内存损坏。在 Windows 上(__cdecl 让我认为您正在使用它),有 Windows 调试工具附带的 gflags 实用程序。有了它,你可以让每个堆分配都有它自己的页面——这将有助于在问题发生时立即捕获内存溢出和双重释放。

我在我的博客上写了说明:

http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx

还有其他提示可以在那里找到这种错误。

于 2008-11-07T13:44:39.887 回答
0

我怀疑你程序的那部分没有问题。最有可能的情况是,您在代码的早期出现了某种内存损坏,而这恰好是它出现的地方。

您是否尝试过在调试模式下通过程序的其余部分(在那部分之后)运行它?如果某种内存损坏,调试模式分配器应该在释放损坏的内存区域时捕获它,如果不是更快的话。当然,假设您使用的是带有彻底调试内存分配器的编译器。

于 2008-11-06T06:23:45.703 回答
0

我怀疑这会影响很多人,因为这相当模糊,但如果你得到你的 FILE* 像这样:

HANDLE hMyFile = CreateFile(...);
FILE* pFile = _fdopen( _open_osfhandle((long)hMyFile, <flags>), "rb" );
CloseHandle(hMyFile);

然后,您将为打开的每个文件泄漏一个流。在执行 _open_osfhandle 和 _fdopen 之后,您必须在 pFile 上调用 fclose() 来关闭您的句柄。CloseHandle 显然不够聪明,无法释放 fdopen 与您的句柄关联的垃圾,但 fclose 足够聪明,可以关闭您的句柄以及与 FILE* 相关的垃圾。

我正在开发的应用程序这样做是因为某个 API 在 HANDLE 周围传递,并且该 API 的特定实现者需要一个 FILE*,所以实现者做了 _fdopen/_open_osfhandle 的东西来获得一个 FILE*。然而,这意味着调用者的 CloseHandle 调用不足以完全关闭 HANDLE。修复方法是首先复制传入的 HANDLE,然后 FILE* 代码可以正确地 fclose() FILE* 而不会破坏调用者的 HANDLE。

示例损坏程序:

#include "stdafx.h"
#include <Windows.h>
#include <io.h>
#include <assert.h>
#include <fcntl.h>
int _tmain(int argc, _TCHAR* argv[])
{

  for(int x = 0;x < 1024; x++)
  {
    HANDLE hFile = CreateFile(L"c:\\temp\\rawdata.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    FILE* pFile =  _fdopen( _open_osfhandle((long)hFile, _O_RDONLY | _O_BINARY), "rb" );
    assert(pFile); // this assert will go off at x=509, because _getstream() only has 512 streams, and 3 are reserved for stdin/stdout/stderr
    CloseHandle(hFile);
  }

    return 0;
}
于 2014-07-21T20:38:37.733 回答
-1

我猜 fileName 出了点问题(它是否有尾随零?)

尝试将fopen行注释掉,看看会发生什么。

于 2008-11-06T05:51:08.140 回答