知識點:吐槽Win7專業版和Win7旗艦版對C++/程式的影響
今天遇到了一個很奇怪的問題,我的電腦是win7+64專業版的,在VC6.0上除錯MFC程式,最後程式關閉的時候,彈出下述警告
但是在Release版本不會出現這個問題,最關鍵的是在同學電腦(Win7+64旗艦版)無論是Debug還是Release都沒問題,弄得我差點重灌系統。
後來,進入提示中的filecore.cpp(這是VC6.0軟體自己的檔案)的295行,程式如下
void CFile::Close() { ASSERT_VALID(this); ASSERT(m_hFile != (UINT)hFileNull);//這裡報錯了 BOOL bError = FALSE; if (m_hFile != (UINT)hFileNull) bError = !::CloseHandle((HANDLE)m_hFile); m_hFile = (UINT) hFileNull; m_bCloseOnDelete = FALSE; m_strFileName.Empty(); if (bError) CFileException::ThrowOsError((LONG)::GetLastError()); }
大意就是說,這個要關閉的檔案控制代碼不能為空,否則報錯。
CGraphicDoc::~CGraphicDoc()
{
delete m_UndoList;
Fundo.Close ();//這裡Fundo不能為空,也就說不能是無效變數
remove(FileName);
}
Release對野指標之類的要求是比Dubug要低的,至於為什麼WIn7旗艦版也能允許,是因為專業版對程式的要求更嚴格了。比如看一下下邊這個問題
void CMyBitmap::make_palette (int a) { if(a==0){ GlobalFreePtr(cp);//全域性釋放cp的控制代碼,cp型別為LPLOGPALETTE* } GlobalFreePtr(cp);//win7專業版會報錯,win7旗艦版不會報錯 }
可以看到:當a為0的時候,執行了兩遍GlobalFreePtr(cp);如果在Win7旗艦版上,函式是可以正常執行的,但是Win7專業版上就不行,第一次執行GlobalFreePtr(cp)後,cp是已經釋放過了,第二次釋放的時候,Winodws會認為是野指標了,專業版會報錯的,但是旗艦版不知是規避了還是沒有處理方正是函式正常退出了。
而解決方法很簡單,上述程式碼只要加上一個else
就可以了
void CMyBitmap::make_palette (int a) { if(a==0){ GlobalFreePtr(cp);//全域性釋放cp的控制代碼,cp型別為LPLOGPALETTE* } else //保證GlobalFreePtr只執行一遍 GlobalFreePtr(cp); }
所以如果大家發現在Win7專業版系統上,經常出現某些程式已停止工作,並不是系統缺東西,而是軟體寫的不夠好(比如說我的有道雲筆記經常提示我“您的有道雲筆記已停止工作~~~~~~~~”)
補充一個MFC框架的知識點:MFC框架程式的退出主要是doc、view、frame的退出,也就是這三個類呼叫各自的解構函式,而呼叫的順序依次為:~ Frame()、~ View()、~ doc()。如果退出的時候,就依照這個順序加斷點除錯就可以了。
最後吐槽一下VC6.0:加斷點除錯的時候,按F10一步一步的走,如果此時進入的程式對應的.cpp檔案沒有在工作空間中開啟,那麼它就會進入彙編的頁面,而不是在編輯器中開啟相應cpp檔案在其中顯示,但是從VS2010以上的版本就可以自動開啟cpp檔案。當VC6.0中出現這樣的情況時,可以在除錯過程中,在彙編頁面加斷點,然後停止除錯執行後,按ctr+B去找加斷點的位置。這也算除錯老程式的無奈之舉了。