更新时间:2015-11-26 12:28:17浏览次数:1+次
一、什么是句柄
从《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。
相关资讯