前言
学习的过程中不太理解句柄是什么,和指针有什么区别,看了一个视频(指针和句柄),感觉大致理解了一点,记录一下,在实际应用中再有理解会继续补充。
一、句柄和指针的区别
1.1 指针
C/C++的内存分区:
- 代码区:存放函数体的二进制代码,由操作系统进行管理
- 全局区:存放全局变量和静态变量以及常量
- 栈区:由编译器自动分配释放,存放函数的参数值、局部变量等
- 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收,在C++中主要利用new在堆区开辟内存,在C语言中使用malloc()
指针的应用离不开堆区和栈区。
用C和C++分别定义指针变量:
int *pAge = malloc(sizeof(int));
int *pAgeCpp = new int;
在栈区开辟了一个4字节的int指针变量,它存储的地址是在堆区new出来的。
1.2 句柄
Windows操作系统下的概念,因此要理解句柄需要从操作系统的内核层理解。
依次为用户层、内核层和硬件抽象层。
用户层中的多个进程想要调用硬件层中的同一个声卡硬件。实际上,操作系统的内核层并不会在每一个进程调用时都单独做一次进行声卡实例化。反之,内核层只做一次唯一的声卡实例化,即SoundCard * pCard = malloc(sizeof(SoundCard));
定义一个SoundCard类型的指针。
那么不同的进程怎么样才能都准确地访问到硬件实例化对象呢?
Windows系统为每一个进程都分配了资源表(句柄表)。资源表中存放了不同的int值,用特定的int值来映射到对应的内核层的某一实例。这些int值就是句柄。
句柄(Handle)的本质就是对底层硬件实例指针的引用。也可以将句柄理解为“索引”。
为什么要用句柄?
句柄可以节约操作系统内核层的资源。
无论对象的位置在内存中如何变化,只要我们掌握了句柄的值,就可以找到区域A,进而找到该对象。而句柄的值在程序本次运行期间是绝对不变的。
下面,关于句柄,再交代一些关键性细节:
(转载自什么是句柄,句柄有什么作用这篇文章)
-
所谓“唯一”、“不变”是指在程序的一次运行中。如果本次运行完,关闭程序,再次启动程序运行,那么这次运行中,同一对象的句柄的值和上次运行时比较,一般是不一样的。其实这理解起来也很自然,所谓“一把归一把,这把是这把,那把是那把,两者不相干”(“把”是形象的说法,就像打牌一样,这里指程序的一次运行)。
-
句柄是对象生成时系统指定的,属性是只读的,程序员不能修改句柄。
-
不同的系统中,句柄的大小(字节数)是不同的,可以使用sizeof()来计算句柄的大小。
-
通过句柄,程序员只能调用系统提供的服务(即API调用),不能像使用指针那样,做其它的事。