现在的位置: 首页 > 综合 > 正文

GDI+ 中 delete 陷阱

2013年06月18日 ⁄ 综合 ⁄ 共 1672字 ⁄ 字号 评论关闭

有时delete GDI+类型的对象会报错.

 

例如

 

Bitmap * pBitmap = new Bitmap;

 

...

 

delete pBitmap;

 

 

正常来说是不会错误的.

 

但是要确保在  GdiplusShutdown(gdiplusToken)之前delete.

 

那当然了.

 

但是容易出现陷阱, 例如下面代码

// 这是VC基于Dialog的工程, 一般都是按照下面的格式使用GDI+, 在CTestDlg中就用到GDI+的各种类.

BOOL CTestApp::InitInstance()

{

     // GDI+ 初始化

     GdiplusStartupInput gdiplusStartupInput;

     ULONG_PTR           gdiplusToken;

     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

 

         CTestDlg dlg;

         m_pMainWnd = &dlg;

         INT_PTR nResponse = dlg.DoModal();

         if (nResponse == IDOK)

         {

              // TODO: 在此处放置处理何时用“确定”来关闭

              //  对话框的代码

         }

         else if (nResponse == IDCANCEL)

         {

              // TODO: 在此放置处理何时用“取消”来关闭

              //  对话框的代码

         }

     //关闭gdiplus的环境

     GdiplusShutdown(gdiplusToken);

 

     // 由于对话框已关闭,所以将返回FALSE 以便退出应用程序,

     //  而不是启动应用程序的消息泵。

     return FALSE;

}

 

问题就出在CTestDlg中的GDI+的使用.

假设你在CTestDlg的构造函数中new一个GDI+对象.

你大多数会在CTestDlg的析构函数中把该GDI+对象中delete.

问题就来了.

 

CTestDlg的析构函数是什么时候被调用的.

BOOL CTestApp::InitInstance()的return FALSE 之后.

但析构CTestDlg之前 GdiplusShutdown(gdiplusToken);已经被调用了

此时delete GDI+的对象就会报错.

简单解决方法

BOOL CTestApp::InitInstance()

{

     // GDI+ 初始化

     GdiplusStartupInput gdiplusStartupInput;

     ULONG_PTR           gdiplusToken;

     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

 

     {

         CTestDlg dlg;

         m_pMainWnd = &dlg;

         INT_PTR nResponse = dlg.DoModal();

         if (nResponse == IDOK)

         {

              // TODO: 在此处放置处理何时用“确定”来关闭

              //  对话框的代码

         }

         else if (nResponse == IDCANCEL)

         {

              // TODO: 在此放置处理何时用“取消”来关闭

              //  对话框的代码

         }

     }

     //关闭gdiplus的环境

     GdiplusShutdown(gdiplusToken);

 

     // 由于对话框已关闭,所以将返回FALSE 以便退出应用程序,

     //  而不是启动应用程序的消息泵。

     return FALSE;

}

 

 

 

抱歉!评论已关闭.