我正在研究性能关键的动态链接库(DLL),它也应该具有相对较小的二进制大小。由于它没有明确地抛出任何异常,我想完全禁用异常支持。但是,有一个例外(双关意外):当内存不足(OOM)时,我必须向应用程序报告错误代码,以便有机会优雅地处理事情。代码库太大,无法单独检查每个分配并传播错误,并包含我不应触及的外部代码。所以我想在我的DLL的导出函数中捕获OOM异常。如何确保禁用C++异常时的内存不足(VS2010)?
一个快速测试表明,当禁用Visual C++ 2010中的C++异常(即无/ EHa,/ EHsc或/ EHs标志)时,它在分配过多内存时仍会跳转到catch(std :: bad_alloc &) 。
所以它似乎按需要工作。但是,我得到以下1级警告:“C4530:使用C++异常处理程序,但展开语义未启用。指定/ EHsc”。 MSDN表示,“在框架中自动存储的对象,在执行抛出的函数和捕获抛出的函数之间,不会被破坏”。
究竟我会在这里失去什么?只要通过库创建的任何内容都可以删除,并且应用程序可以重新开始(如果可以的话),就可以将事物置于未定义的状态。是否存在无法恢复的内存泄漏风险?
DLL是否使用单独的内存池?如果是这样,我可以清除它而无需应用程序卸载DLL?我可以轻松地让我的库忽略任何进一步的(导出)函数调用,直到应用程序执行重新初始化。
感谢您的建议。
* DLL是否使用单独的内存池?* http://stackoverflow.com/questions/10820114/do-statically-linked-dlls-use-a-different-heap-than-the-main-program – thang
*如果是这样的话,我可以在不需要应用程序卸载DLL的情况下清除它吗?是的,只需从new中删除这些东西,然后从malloc中释放这些东西。 – thang
没有异常处理意味着堆栈上(以及失败的构造函数内)创建的对象不会被销毁。如果你只是在'bad_alloc'发生时退出,那么你很好,我想[只要你没有奇怪的资源,不会被程序退出清理 - 但大多数应该]。如果你想在'bad_alloc'后面“继续”,那么代码将需要跟踪对象并销毁在'throw'和'catch'之间的栈帧中创建的所有对象。你可以通过编写一些在解析器中打印输出的小代码来体验。 –