为什么`_getstream'会失败?

时间:2008-11-06 02:22:16

标签: c++ file fopen

例外提及

FILE* __cdecl _getstream

我正在呼叫fopen并且它一直在崩溃。

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

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

4 个答案:

答案 0 :(得分: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

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

答案 1 :(得分:0)

我怀疑你的程序部分没有任何问题。最可能的情况是你在代码中早些时候遇到了某种内存损坏,而这恰好就是它出现的地方。

您是否尝试在调试模式下运行程序的其余部分(在该部分之后)?如果 某种类型的内存损坏,调试模式分配器应该在它解除损坏的内存区域时捕获它,如果不是更快的话。假设您正在使用带有完整调试内存分配器的编译器。

答案 2 :(得分:0)

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

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

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

我正在处理的应用程序是这样做的,因为某个API在HANDLEs周围传递,并且API的特定实现者需要一个FILE *,因此实现者使用_fdopen / _open_osfhandle来获取文件*。但是,这意味着呼叫者的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;
}

答案 3 :(得分:-1)

我想fileName有问题(它是否有尾随零?)

尝试评论 fopen ,看看会发生什么。