![]() |
|
||||||
GetDC使用中容易忽视的bug written by Panic 2006/07/20 The GetDC function retrieves a common, class, or private DC depending on the class style specified for the specified window. For common DCs, GetDC assigns default attributes to the DC each time it is retrieved. For class and private DCs, GetDC leaves the previously assigned attributes unchanged. After painting with a common DC, the ReleaseDC function must be called to release the DC. Class and private DCs do not have to be released. The number of DCs is limited only by available memory. 关键是这一句: After painting with a common DC, the ReleaseDC function must be called to release the DC. 但是由于GetDC直接返回一个指向CDC的指针(SDK中,返回的是一个HDC句柄),所以可以用这种形式的调用: GetDC()->XXXXXX 但是这样一来,由于返回值没有保存,就无法进行ReleaseDC的调用了,由此会引起一个GDI资源泄漏。表现就是程序使用的GDI资源数量增加1。 在Win2k下,每个进程的可用GDI资源总数为10000,所以一般情况下这种泄漏不会引起什么实际的问题。但是,当程序需要频繁刷新,或者构造大量GDI对象的时候,就会面临GDI资源耗尽的问题。 GDI资源耗尽,导致的后果是无法创建新的GDI对象,但是在MFC中,GDI对象的构造函数不会因此而抛出异常(因为许多时候,实际的GDI对象不是在构造函数中建立的)。 由于GDI对象创建失败是很罕见的情况,而且失败了,也几乎没什么挽救手段,所以相当多的代码都不检测GDI对象创建是否成功。 以上这些同时存在于一个工程中的时候,就会引起一个难以觉察的bug,他的表现是GDI出现异常显示或者其他错误,直接原因是GDI对象创建失败,本质原因是没有对GetDC得到的返回值做ReleaseDC的调用,导致GDi资源耗尽。 也许其他的Get函数也有类似的问题。 我在msdn上没找到GDI对象总数限制的内容,10000个是我在win2kpro sp4上实测的结果。 |
|||||||
|
|||||||
| GetDC使用中容易忽视的bug < 上一篇 | 下一篇 > 有圣斗士 的网 |

