2008-10-17 10 views
5

我正在處理MFC應用程序的大型老化代碼庫。隨着時間的推移,許多開發人員一直在研究這些代碼,因此,在處理新分配失敗的可能性的代碼中,我們有三種不同的方法。執行沒有鏈接到MFC項目的mfc的C++靜態庫throw bad_alloc或CMemoryException *?

第一種方法是在新的結果上測試NULL。我們不使用nothrownew.obj,所以這顯然是一個需要清理的錯誤。

其次是捕捉CMemoryException *(是的,C++異常在編譯器中啓用)。據我所知,MFC覆蓋了新的標準運算符,而是拋出這個東西。我相當肯定,第二種方法在MFC應用程序本身中是正確的。 MFC覆蓋新的,其奇怪的CMemoryException引發版本。

最後一個來自我們的人,他們擅長使用C++,但不是MFC程序員。他們正在捕獲const std :: bad_alloc &。

我真的不知道的是鏈接到應用程序的靜態庫的期望。這是絕大多數使用bad_alloc的代碼。假設這些庫不是用MFC或ATL編譯的,而是僅用標準C++編寫的,他們是否可以捕獲bad_alloc?或者,他們鏈接的應用程序中是否存在MFC,並使用全局新運算符感染它們,並使其嘗試在錯誤的分配模擬中乾淨地失敗?

如果你有答案,你能解釋這是如何工作的,或者指出我正確的參考來解決這個問題嗎?

回答

3

這取決於要鏈接到靜態庫的編譯選項應用程序。

如果使用配置編譯庫以使用標準C++運行時的靜態那麼我期望調用標準C++運行時的operator new

如果庫與配置使用標準的C++運行時DLL然後這些功能的分辨率將被延遲,直到程序加載和解析爲的operator new的MFC替換編譯。

我還包括一個鏈接到這個香草Sutter article關於處理分配錯誤,你可能會覺得有用。

+0

謝謝!我們鏈接到標準的C++運行庫作爲DLL,這意味着每個人都有MFC異常。不幸的是,這個應用程序的主要目標之一是沒有虛擬內存的系統,所以需要進行分配檢查,呃。 – 2008-10-17 22:56:06

1

恭喜你 - 你似乎已經把我們所有人都絆倒了。 :-)

理論上,如果MFC爲全局函數提供了一個過載函數,那麼它應該在程序中使用全部代碼。但是由於靜態庫的編譯不知道,我不能肯定地說它會。

我可以建議的最好的方法是編寫一些測試代碼來找出答案。 (我在接下來的幾個小時內無法訪問我的Windows系統,或者我自己也會這樣做並給你一個答案。)

+0

0123這樣,我的同齡人也難倒了,沒有人能想出一個好方法迫使新的失敗,而不是超載新的首先。精益:) – 2008-10-17 22:08:36

0

您可以使用AfxSetNewHandler(_PNH pfnNewHandler)更改MFC投擲行爲,並提供指向您自己的NewHandler函數的指針。這個函數應該拋出一個std::bad_alloc異常。 但是現在MFC程序部分有問題要趕上std::bad_alloc

1

我已經做了一些MFC代碼研究(在VC2010)。這裏有一些事實。

  1. 的MFC拋出一個指向名爲 「_simpleMemoryException」 全球CMemoryException實例(也見AfxThrowMemoryException())
  2. 這是一個了CException,其m_bAutoDelete是假的。

想法:如果有可能改變C++ - 只有靜態庫,你可以轉發聲明class CException;和/或class CMemoryException;到根命名空間。

std::bad_alloc-catch塊的每個位置添加一個帶catch (CMemoryException* pEx) {...}和/或catch (CException* pEx) {...}的捕獲塊。由於catched指針是指向全局對象的指針,因此不需要調用pEx->Delete();

以這種方式,C++-only-static-libraries不需要包含afx.h或/和針對MFC的鏈接。我試過它在VC2010,它工作正常。 (只有當RTTI被啓用,並且只有在沒有人用AfxSetNewHandler將MFC-NewHandler更改爲默認MFC-NewHandler之外的其他內容時)