fiscblog
fiscblog

Reputation: 694

How are Handles managed properly?

This is a very basic question about the correct use of a HANDLE. Given the following code (it is not a particular source file):

typedef void* HANDLE;

HANDLE myHandle;

myHandle = SomeObject;

//...some elaborate code...//
  1. First question: Is myHandle now located on the Stack or Heap? Since a Handle can be a pointer as well as just an index I am not quite sure about that.

    At the point myHandle is out of scope it is removed (at least I think so). But in case it is a class member it remains visible until the owning object was deleted. So second question:

  2. If I want to avoid any further access to myHandle, is it good practice to do

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

    Would I run into a conflict with memory management now, or any other restrictions regarding managed code? Are there other options to state that this handle should not be used anymore similar to pointers:

    mypointer = NULL;
    

EDIT: I was talking about garbage collection in first place which is obviously not included in c++. This is a part of managed extensions. Thanks for helping me out with this fatal error!

Upvotes: 1

Views: 594

Answers (3)

Damon
Damon

Reputation: 70136

You are probably a Java programmer from the assumptions that you make.

The variable myHandle is indeed allocated on the stack, and it is removed when it goes out of scope, although not by a garbage collector (no such thing exists in C++).

However, this does not free the handle (myHandle is just a variable that holds some opaque numeric value, the actual handle is owned by the OS -- so its lifetime is not identical to the lifetime of any arbitrary variable holding that value). You must do this yourself using the appropriate API function (for most things that are a HANDLE, this is CLoseHandle), preferrably with a "handle holder" class so it is exception-safe.

A simple implementation of such a handle holder could look like this:

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

That way, you assign to a AutoHandle variable when opening a resource, and when it goes out of scope, the handle is closed. You cannot forget to do it, and it will even work if an exception occurs.

Upvotes: 1

Shar
Shar

Reputation: 455

Usually prefer to use delete before put a pointer to NULL.

But for a HANDLER don't put it to NULL yourself !

Upvotes: 0

bash.d
bash.d

Reputation: 13207

As you have not specified what HANDLEs you are talking about, I assume Windows handles.

A HANDLE is an opaque data-type (mostly represents a number the OS can work with) and should be treated only by system-functions such as CreateFile or CloseHandle.

You should never set a HANDLE to 0 by yourself as you are losing the associated resource.

See CloseHandle, CreateFile(especially the Return Value), and Windows Data Types.

From Wikipedia

In computer programming, a handle is an abstract reference to a resource. Handles are used when application software references blocks of memory or objects managed by another system, such as a database or an operating system.

While a pointer literally contains the address of the item to which it refers, a handle is an abstraction of a reference which is managed externally; its opacity allows the referent to be relocated in memory by the system without invalidating the handle, which is impossible with pointers. The extra layer of indirection also increases the control the managing system has over operations performed on the referent. Typically the handle is an index or a pointer into a global array of tombstones.


And C++ does not have a garbage collection by the Standard, this is why you need to delete newed objects yourself, but not handles given by the system!

Upvotes: 1

Related Questions