C++:吐槽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去找加斷點的位置。這也算調試老程序的無奈之舉了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章