如何正确地管理句柄

How are Handles managed properly?

本文关键字:句柄 管理 正确地      更新时间:2023-10-16

这是一个关于HANDLE正确使用的非常基本的问题。给定以下代码(它不是特定的源文件):

typedef void* HANDLE;
HANDLE myHandle;
myHandle = SomeObject;
//...some elaborate code...//
  1. 第一个问题:myHandle现在位于堆栈或堆上吗?因为句柄可以是一个指针,以及只是一个索引,我不太确定。

    在myHandle超出作用域时,它被删除(至少我认为是这样)。但如果它是一个类成员,它将保持可见,直到所属对象被删除。第二个问题:

  2. 如果我想避免任何进一步访问myHandle,这是一个好的做法,做

    myHandle = 0;  // I do not need this handle anymore
    

    我现在是否会遇到内存管理的冲突,或者关于托管代码的任何其他限制?是否有其他选项来声明该句柄不应该再使用,类似于指针:

    mypointer = NULL;
    

编辑:我首先说的是垃圾收集,这显然不包括在c++中。这是托管扩展的一部分。谢谢你帮我解决这个致命的错误!

从您所做的假设来看,您可能是一个Java程序员。

变量myHandle确实是在堆栈上分配的,当它超出作用域时,它被删除,尽管不是由垃圾收集器(在c++中不存在这样的东西)。

然而,并没有释放句柄(myHandle只是一个保存一些不透明数值的变量,实际的句柄是由操作系统拥有的——所以它的生命周期与任何保存该值的任意变量的生命周期并不相同)。您必须自己使用适当的API函数(对于大多数HANDLE,这是CLoseHandle),最好使用"句柄持有人"类,这样它是异常安全的。

这样一个句柄持有人的简单实现可能像这样:

class AutoHandle
{
    HANDLE handle;
public:
    AutoHandle(HANDLE in) : handle(in) {}
    ~AutoHandle() { CloseHandle(handle); }
};

这样,您在打开资源时分配给AutoHandle变量,当它超出作用域时,句柄被关闭。您不会忘记这样做,即使发生异常,它也会工作。

由于您没有指定您正在谈论的HANDLE s,我假设Windows句柄。

HANDLE是一种不透明的数据类型(主要表示操作系统可以处理的数字),应该只由系统函数(如CreateFileCloseHandle)处理。

你不应该自己将HANDLE设置为0,因为你会丢失相关的资源。

参见CloseHandle、CreateFile(特别是返回值)和Windows数据类型。

从维基百科

在计算机编程中,句柄是对资源的抽象引用。句柄在应用程序软件引用由另一个系统(如数据库或操作系统)管理的内存块或对象时使用。

指针实际上包含它所指向的项的地址,而句柄是外部管理的引用的抽象;它的不透明性允许系统在不使句柄失效的情况下在内存中重新定位引用,这对于指针来说是不可能的。额外的间接层还增加了管理系统对在引用上执行的操作的控制。句柄通常是指向全局墓碑数组的索引或指针。


和c++没有垃圾收集标准,这就是为什么你需要删除new ed对象自己,而不是由系统给出的句柄!

通常更倾向于在放置指向NULL的指针之前使用delete。

但是对于一个HANDLER,不要自己把它设为NULL !