为什么 `_getstream` 会失败?
异常提到
FILE* __cdecl _getstream
我正在调用 fopen
并且它不断崩溃。
AfxMessageBox("getting here 1");
FILE* filePtr = fopen(fileName, "rb");
AfxMessageBox("getting here 2");
由于某种原因,我从来没有进入第二个消息框。 有趣的是,当我处于调试模式时,该应用程序运行良好。 为什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为内存损坏。 在 Windows 上(__cdecl 让我认为您正在使用它),Windows 调试工具附带了 gflags 实用程序。 有了它,您可以使每个堆分配都有它自己的页面——这将有助于在问题发生时立即捕获内存溢出和双重释放。
我在博客上写了说明:
http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx
有还有其他查找此类错误的技巧。
I think memory corruption. On Windows (which the __cdecl makes me think you are using), there is the gflags utility which comes with the Windows Debugging Tools. With it, you can make each heap allocation have it's own page -- this will help catch memory overruns and double freeing immediately at the point of the problem.
I wrote up instructions on my blog:
http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx
There are other tips for finding this kind of bug there too.
我怀疑你的程序的那部分没有任何问题。 最有可能的情况是,您在代码的早期部分出现了某种内存损坏,而这恰好是它出现的地方。
您是否尝试过在调试模式下运行程序的其余部分(在那部分之后)? 如果它是某种内存损坏,那么调试模式分配器应该在释放损坏的内存区域时捕获它,如果不是更早的话。 当然,假设您使用的是带有彻底调试内存分配器的编译器。
I would suspect there's nothing wrong with that part of your program. The most likely scenario is that you've got some kind of memory corruption earlier in the code, and that just happens to be where it shows up.
Have you tried running it through the rest of the program (after that part) in debug mode? If it is some kind of memory corruption, the debug-mode allocator should catch it when it goes to deallocate the corrupted areas of memory, if not sooner. Assuming you're using a compiler with a thorough debugging memory allocator, of course.
我怀疑这会影响很多人,因为这是相当晦涩的,但如果你像这样得到 FILE*:
那么你将泄漏你打开的每个文件的流。 在执行 _open_osfhandle 和 _fdopen 之后,您必须在 pFile 上调用 fclose() 来关闭句柄。 CloseHandle 显然不够聪明,无法释放 fdopen 与您的句柄关联的残骸,但 fclose 足够聪明,可以关闭您的句柄以及与 FILE* 相关的残骸。
我正在开发的应用程序这样做是因为某个 API 传递了 HANDLE,并且该 API 的特定实现者需要 FILE*,因此实现者执行 _fdopen/_open_osfhandle 操作来获取 FILE*。 然而,这意味着调用者的 CloseHandle 调用不足以完全关闭 HANDLE。 修复方法是首先复制传入的 HANDLE,然后 FILE* 代码可以正确地 fclose() FILE* 而不会破坏调用者的 HANDLE。
损坏的程序示例:
I doubt this will affect many people since this is fairly obscure, but if you get your FILE* like this:
Then you'll leak a stream for each file you open. After doing _open_osfhandle and _fdopen, you must call fclose() on the pFile to close your handle. CloseHandle is apparently not smart enough to free the cruft that fdopen associates with your handle, but fclose is smart enough to close your handle along with the FILE*-related cruft.
The app I was working on did this because a certain API passed around HANDLEs, and a particular implementor of the API needed a FILE*, so the implementor did the _fdopen/_open_osfhandle stuff to get a FILE*. However, this meant that the caller's CloseHandle call was insufficient to fully close the HANDLE. The fix was to duplicate the incoming HANDLE first, then the FILE* code could properly fclose() the FILE* without breaking the caller's HANDLE.
Sample broken program:
我猜想 fileName 有问题(它是否有尾随零?)
尝试注释 fopen 行,看看会发生什么。
I guess that something is wrong with fileName (does it have trailing zero ?)
Try to comment fopen line out and see what will happen.