代码之家  ›  专栏  ›  技术社区  ›  baash05

为什么“getstream”会失败?

  •  1
  • baash05  · 技术社区  · 17 年前

    例外提到

    FILE* __cdecl _getstream
    

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

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

    由于某种原因,我从来没有进入第二个信息框。有趣的是,当我处于调试模式时,这个应用程序工作得非常好。为什么?

    4 回复  |  直到 11 年前
        1
  •  2
  •   Lou Franco    17 年前

    我认为记忆会被破坏。在Windows上(cdecl让我觉得你在使用它),Windows调试工具附带了gflags实用程序。有了它,您可以让每个堆分配都有自己的页面——这将有助于捕获内存溢出,并在出现问题时立即释放内存。

    我在博客上写下了说明:

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

    在那里也有找到这种bug的其他技巧。

        2
  •  0
  •   Head Geek    17 年前

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

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

        3
  •  0
  •   ArtHare    12 年前

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

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

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

    我正在开发的应用程序之所以这样做,是因为某个API传递了句柄,而该API的特定实现者需要一个文件*,所以实现者执行了_fdopen/_open _osfhandle操作来获取一个文件*。然而,这意味着调用方的CloseHandle调用不足以完全关闭句柄。修复方法是首先复制传入句柄,然后FILE*代码可以在不破坏调用方句柄的情况下正确地fclose()文件*。

    示例程序:

    #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;
    }
    
        4
  •  -1
  •   Dmitry Khalatov    17 年前

    我猜文件名有问题(后面有零吗?)

    试着发表评论 福彭 排好队,看看会发生什么。