知识点:吐槽Win7专业版和Win7旗舰版对C++/程序的影响

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dashumak/article/details/84257043

今天遇到了一个很奇怪的问题,我的电脑是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去找加断点的位置。这也算调试老程序的无奈之举了。

猜你喜欢

转载自blog.csdn.net/dashumak/article/details/84257043
今日推荐