当前位置:C++技术网 > 资讯 > win32 简单预防句柄溢出

win32 简单预防句柄溢出

更新时间:2015-11-26 12:28:17浏览次数:1+次

win32 简单预防句柄溢出

一、什么是句柄

从《windows内核编程》这本书里面有写,你要是问我,句柄是什么?我想了一下,真回答不出来。如果叫我通俗地叙述,我会说,这是一个“对象”的标记值,而这个值是用来控制你要操作的对象的。

用图简单描述:

 

如果你还是觉得这个图难以理解,那么请看windows核心编程》第五版 下载。

 

二、为什么很多书籍都强调closehandle(),或者 deleteObject()

场景①

如果你做过多线程,那么你经常会见到

Auto h = (HANDLE)_beginthreadex(); //启动一个线程

Close(h); //关闭线程句柄

为什么h调用以后,要做close()?为什么close()以后就没有句柄溢出,那么你应该什么时候去调用close(),什么时候又不能太早去调用?

 

场景②

HDC dc;

HBITMAP bitmap;

HBITMAP old =  SelectObject(dc,bitmap);  //选择一个bitmap

//使用

SelectObject(dc,old); //选回旧的

DeleteObject(bitmap);

如果我们新建一个句柄以后,又不进行释放。这就像 new 以后没有delete,没有释放的后果是:程序不断执行,句柄不断溢出,内存溢出,崩溃。要注意的是,释放次数也是有规定的,一次就是一次,两次就是两次。一一对应。

三、认识计数器,要知道windows 什么时候可能会帮句柄加1计数

Windows怎么知道某个句柄所指定的资源被占用了,怎么知道已经没有程序去用他了?简单来说,每个句柄都有相对应的计数器,当你create以后+1,当被一个对象selectObject(dc,new)以后+1,当该对象SelectObject(dc,other)了其他对象以后被弹出,会-1。具体也是需要看《windows核心编程》,你必须清楚,什么时候会+1,什么时候会-1。要知道计数器减到什么时候,就可以了。在调用api以前应该要这个API是否会把计数器+1,是否会把其他句柄的计数器-1

例如_beginthreadex();要closehandle(),-1;

_beginthread()却不用。如果勉强去closehandle会出现未定义行为。

那么我们怎么去避免这种情况?

1、 查MSDN看标准的事例、用法

2、 查百度百科的事例、用法

3、 看别人写的代码,最好带注释

4、 学习、提高自己的防范意识,使用前后要审核句柄有没有泄漏

5、 不轻易直接复制别人的一大段代码,特别是win32。