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...//
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:
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!
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.
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!
Usually prefer to use delete before put a pointer to NULL.
But for a HANDLER don't put it to NULL yourself !
Related
I have read this article and I encountered the following
A resource handle can be an opaque identifier, in which case it is
often an integer number (often an array index in an array or "table"
that is used to manage that type of resource), or it can be a pointer
that allows access to further information.
So a handle is either an opaque identifier or a pointer that allows access to further information. But from what I understand, these specific pointers are opaque pointers, so what exactly is the difference between these pointers ,which are opaque pointer, and opaque identifiers?
One of the literal meanings of "opaque" is "not transparent".
In computer science, an opaque identifier or a handle is one that doesn't expose its inner details. This means we can only access information from it by using some defined interface, and can't otherwise access information about its value (if any) or internal structure.
As an example, a FILE in the C standard library (and available in C++ through <cstdio>) is an opaque type. We don't know if it is a data structure, an integer, or anything else. All we know is that a set of functions, like fopen() return a pointer to one (i.e. a FILE *) and other functions (fclose(), fprintf(), ....) accept a FILE * as an argument. If we have a FILE *, we can't reliably do anything with it (e.g. actually write to a file) unless we use those functions.
The advantage of that is it allows different implementations to use different ways of representing a file. As long as our code uses the supplied functions, we don't have to worry about the internal workings of a FILE, or of I/O functions. Compiler vendors (or implementers of the standard library) worry about getting the internal details right. We simply use the opaque type FILE, and pointers to it, and stick to using standard functions, and our code works with all implementations (compilers, standard library versions, host systems)
An opaque identifier can be of any type. It can be an integer, a pointer, even a pointer to a pointer, or a data structure. Integers and pointers are common choices, but not the only ones. The key is only using a defined set of operations (i.e. a specific interface) to interact with those identifiers, without getting our hands dirty by playing with internal details.
A handle is said to be "opaque" when client code doesn't know how to see what it references. It's simply some identifier that can be used to identify something. Often it will be a pointer to an incomplete type that's only defined within a library and who's definition isn't visible to client code. Or it could just be an integer that references some element in some data structure. The important thing is that the client doesn't know or care what the handle is. The client only cares that it uniquely identifies some resource.
Consider the following interface:
widget_handle create_widget();
void do_a_thing(widget_handle);
void destroy_widget(widget_handle);
Here, it doesn't actually matter to the calling code what a widget_handle is, how the library actually stores widgets, or how the library actually uses a widget_handle to find a particular widget. It could be a pointer to a widget, or it could be an index into some global array of widgets. The caller doesn't care. All that matters is that it somehow identifies a widget.
One possible difference is that an integer handle can have "special" values, while pointer handle cannot.
For example, the file descriptors 0,1,2 are stdin, stdout, stderr. This would be harder to pull off if you have a pointer for a handle.
You really you shouldn't care. They could be everything.
Suppose you buy a ticket from person A for an event. You must give this ticket to person B to access the event.
The nature of the ticket is irrelevant to you, it could be:
a paper ticket,
an alphanumerical code,
a barcode,
a QR-Code,
a photo,
a badge,
whatever.
You don't care. Only A and B use the ticket for its nature, you are just carrying it around. Only B knows how to verify the validity and only A know how to issue a correct ticket.
An opaque pointer could be a memory location directly, while an integer could be an offset of a base memory address in a table but how is that relevant to you, client of the opaque handle?
In classic Mac OS memory management, handles were doubly indirected pointers. The handle pointed to a "master pointer" which was the address of the actual data. This allowed moving the actual storage of the object in memory. When a block was moved, its master pointer would be updated by the memory manager.
In order to use the data the handle ultimately referenced, the handle had to be locked, which would prevent it being moved. (There was little concurrency in the system so unless one was calling the operating system or libraries which might, one could also rely on memory not getting moved. Doing so was somewhat perilous however as code often evolved to call something that could move memory inside a place where that was not expected.)
In this design, the handle is a pointer but it is not an opaque type. A generic handle is a void ** in C, but often one had a typed handle. If you look here you'll find lots of handle types that are more concrete. E.g. StringHandle.
I am using boost shared pointers and these pointers are really shared all over the application. There are conditions, where such a shared pointer becomes invalid. For example, a shared pointer to a network resource, that can become invalid because network became unavailable. In such a scenario, where the shared pointer becomes invalid, i would like all objects to stop using it. How can i send a message to all objects that the pointer is invalid. If it was a normal pointer, i could set it to null and all client code should be checking for null pointer before using it. But, in case of a shared pointer, which keeps reference count, how can i achieve similar functionality ?
You can use weak pointers. That is, the code that handles the network events has the shared_ptr<Res> while everybody else has a weak_ptr<Res>. Now,
when the resource becomes unavailable, just reset the shared_ptr to NULL;
when a client wants to use the resource, call lock() into the weak_ptr and test whether the returned shared_ptr is valid before using.
If it was a normal pointer, i could set it to null and all client code should be checking for null pointer before using it.
I doubt that. You'd then have copies of that raw pointer that point to invalid objects. You'd think that would solve the problem, but it doesn't. It amplifies it.
The fact is that the shared pointer itself doesn't become invalid, the object it contains does. So, logically, whether it's still safe to use it should be contained in the object, not the shared pointer.
a shared pointer to a network resource, that can become invalid because network became unavailable.
Just throw an exception when you attempt to call a method that attempts to use the network...
I would be inclined to follow the pattern used by standard streams: have an object that represents the resource, which can enter an error state and/or throw an exception when it detects (or is informed) that the network is no longer available. If you can't change the existing resource class, then this new object can hold the existing resource object (that currently all your users have shared pointers to), and the users can share the new object.
Unless you need all the users of this resource to respond promptly when it becomes unavailable, there doesn't seem any point trying to propagate a message to them all. If you just want them to stop using it, they can do that the next time they try to use it, and discover that it doesn't work any more. If they do really need a message, then write something to keep a list of them all, and call some function on them when the event that they're interested in occurs. This is called the Observer pattern or "listeners", and armed with those search terms you can find implementations and alternatives.
Ideally, users should be able to check for the error state either as part of using the resource, or immediately afterwards. Testing before use is usually error-prone, since it creates a window in which the network perhaps could become unavailable after the test but before it's used. Once your code has to handle that case correctly you might as well make it the only case, by not bothering to check in advance.
You need to store more information. You could put the resource together with a bool in a tuple, or you could use boost::optional, and set it to none when you want to invalidate it.
You almost certainly shouldn't be using shared pointer for this, since
its semantics don't correspond to what you need. Shared pointer
implements a sort of poor man's garbage collection, where the object
ceases to exist when there are no more pointers to it; you need the
opposite, that the pointers to the object cease to exist when there is
no more object. (A reverse garbage collection, so to speak.)
I've used a ManagedPtr in the past; the pointer registers itself with
the object, which must derive from a ManagingObj class which sets the
pointers to null in its destructor. This works sometimes, but it still
doesn't remove entries from lists, etc. where the other objects may be
keeping it. And in practice, other objects which know about your
network resource object may want to take specific actions when it
disappears. In the end, you almost always need to use the observer
pattern: any object which acquires a pointer to your object registers
with it to be notified in case of its demise.
I've been told that a handle is a sort of "void" pointer. But what exactly does "void pointer" mean and what is its purpose. Also, what does "somehandle = GetStdHandle(STD_INPUT_HANDLE); do?
A handle in the general sense is an opaque value that uniquely identifies an object. In this context, "opaque" means that the entity distributing the handle (e.g. the window manager) knows how handles map to objects but the entities which use the handle (e.g. your code) do not.
This is done so that they cannot get at the real object unless the provider is involved, which allows the provider to be sure that noone is messing with the objects it owns behind its back.
Since it's very practical, handles have traditionally been integer types or void* because using primitives is much easier in C than anything else. In particular, a lot of functions in the Win32 API accept or return handles (which are #defined with various names: HANDLE, HKEY, many others). All of these types map to void*.
Update:
To answer the second question (although it might be better asked and answered on its own):
GetStdHandle(STD_INPUT_HANDLE) returns a handle to the standard input device. You can use this handle to read from your process's standard input.
A HANDLE isn't necessarily a pointer or a double pointer, it may be an index in an OS table as well as anything else. It's defined for convenience as a void * because often is used actually as a pointer, and because in C void * is a type on which you can't perform almost any operation.
The key point is that you must think at it as some opaque token that represents a resource managed by the OS; passing it to the appropriate functions you tell them to operate on such object. Because it's "opaque", you shouldn't change it or try to dereference it: just use it with functions that can work with it.
A HANDLE is a pointer to a pointer, it's pretty much as simple as that.
So to get the pointer to the data, you'd have to dereference it first.
GetStdHandle(STD_INPUT_HANDLE) will return the handle to the stdin stream - standard input. That's either the console or a file/stream if you invoke from the command prompt with a '<' character.
A Windows HANDLE is effectively an index into an array of void pointers, plus a few other things. A void pointer (void*) is the pointer that points to an unknown type and should be avoided at all costs in C++- however the Windows API is C-compatible and uses it to avoid having to expose Windows internal types.
GetStdHandle(STD_INPUT_HANDLE) means, get the HANDLE associated to the Standard output stream.
I came across a leak in a Direct3D application of mine, and I ended up correcting it, but I think the cause of the leak was due to my misunderstanding of how Direct3D handles its memory and interfaces.
I haven't been able to find a definitive article/tutorial on it (please provide one if you have one), but from what I've gathered, it works as such:
Every time you call a Get method, the number of references for the object returned is incremented. So if I call GetRenderTarget, the surface being rendered to has its reference count incremented.
Calling Release on the interface decrements its reference count. These first two points combined essentially mean: every time you get an interface, release it after you're done with it.
When the reference count reaches 0, the instance is deleted.
I'm not entirely sure if this is correct, but it seems to work in practice. If someone could clarify/confirm how it works, that'd be great.
P.S, are there any safeguards implemented in releasing interfaces? Calling Release any number of times on the back buffer doesn't seem to do any damage (which is a good thing, but I'm not sure why it doesn't).
Direct3D is based on COM, which is a technology that's at least 15 years old. Seems many people claim COM is dead and for that reason many overlook it, but reality is that there are many things in windows including Direct3D and MS's new Media Foundation that are all based on COM.
I strongly suggest you take a look at general COM programming. There are plenty of books and resources, but many of them are rather old but that's ok because the root of the technology hasn't changed for a very long time.
Basically what you've observed is interface reference counting. COM is based purely on accessing objects via interfaces, which all derive from the base interface, IUnknown. IUnknown implements methods AddRef() and Release() and it is the responsibility of your application to call AddRef() whenever you store a local copy of a pointer and to call Release() whenever that local copy is no longer needed.
When you have methods with interface out parameters (i.e. IFoo** ppObj ), that means the callee is giving you back an interface and now that you have it, it is still your responsibility to call Release() whenever you are done with it.
Once you get the hang of it, I'd suggest you start using CComPtr smart class for storing local and member variables (still pass raw interface values between function calls, no need for smart pointer parameter types). It will take care of all your reference counting. Also don't make it a practice of calling release "any number" of times. It might work today because the object is implemented as a singleton, or maybe something else is holding on to it, but that might change with next patch or next release. Always follow the rules. If you have an interface, when you don't need it call Release() exactly once. If you made a copy of interface pointer, make sure to call AddRef() exactly once.
The application of addref/release semantics is much wider than COM technology. There is simple rule one CreateObject() (or CreateTexture, or GetRenderTarget, or GetBackBuffer, etc...) have to be confronted with one Release(), one AddRef() have to be confronted with one Release().
In COM IUnknown::Release() returns number of references to object. It may delude you and you can think:
"Hm... I just call Release() until it return 0 and I will have no leaks. ???? PROFIT!!!!!111" <-- That is wrong! AddRef might be called by Direct3D itself or by 3rd_party library you pass this object to, or something else outside your app. One Release for one AddRef. You should call Release when you don't need object anymore, don't waste system resources.
You said:
Calling Release any number of times on the back buffer doesn't seem to do any damage
That means nothing. May be The Universe like you so much or you just too lucky to not get exceptions from D3D.
Smart pointers (such as CComPtr) could make your life much easier if you will use them. In this case you don't need to call Release explicitly, it is called in CComPtr dtor if it is assigned to some object.
void get_surface(IDirect3DDevice9 *pDevice)
{
IDirect3DSurface9 *surf0;
IDirect3DSurface9 *surf1;
CComPtr<IDirect3DSurface9> surf2;
CComPtr<IDirect3DSurface9> surf3;
CComPtr<IDirect3DSurface9> surf4;
pDevice->GetRenderTarget( 0, surf0 ); // surface reference counter incremented, you should call Release() for this
surf1 = surf0; // surface reference count is not incremented, you shouldn't call Release() for this
pDevice->GetRenderTarget( 0, surf2 ); // surface reference counter incremented
CComPtr<IDirect3DSurface9> surf3 = surf0; // surface reference counter incremented
surf0->Release(); // release for pDevice->GetRenderTarget( 0, surf0 );
surf2.Release(); // .Release() used not ->Release() - it is important
surf4.Release(); // nothing happens because surf4 == 0
} // surf3.Release() is called in surf3 destructor
Also you may #define D3D_DEBUG_INFObefore including direct 3d headers and switch to debug d3d runtime. It is helpful in finding leaks in d3d app.
May the CComPtr Force be with you.
D3D objects are COM objects, and they use a basic reference counting system to manage the lifetime of the object. (See wikipedia for more info about the Component Object Model, or the MSDN article Managing Object Lifetimes)
The reference count is modified purely through the AddRef/Release methods, and certain other functions call those methods.
Creating the object as well as calling certain Get methods that return an object derived from the IUnknown class will call AddRef internally to increment the reference count, so you will need to call Release for each call when you are finished with the object.
If you pass the object to another function or class that stores a copy of the point (even temporarily) that class/function should call AddRef to ensure that the object is not freed while it is using it (and Release to signal it is done).
When the reference counter reaches 0 from a call to Release the object is signalled that it may be a good time to delete the held resources, but it may not happen immediately. There is also no protection for calling Release multiple times. The reference counter will not become negative, but it will not perform any other sanity checking (because it can't really) so you can cause application instability by trying to release references you don't hold.
Yes, you are correct. This is called reference counting and it ensures that objects are alive as long as they are being used, and no longer. You can use a variety of smart pointers to enforce this rule- both shared_ptr and (C++11) unique_ptr allow for custom deleters to call Release(). This makes it easy to control the lifetime of Direct3D objects just like you would for any other object in your application. You don't need to start including ATL libraries and CComPtr to use smart pointers with COM interfaces.
I have been told that a handle is sort of a pointer, but not, and that it allows you to keep a reference to an object, rather than the object itself. What is a more elaborate explanation?
A handle can be anything from an integer index to a pointer to a resource in kernel space. The idea is that they provide an abstraction of a resource, so you don't need to know much about the resource itself to use it.
For instance, the HWND in the Win32 API is a handle for a Window. By itself it's useless: you can't glean any information from it. But pass it to the right API functions, and you can perform a wealth of different tricks with it. Internally you can think of the HWND as just an index into the GUI's table of windows (which may not necessarily be how it's implemented, but it makes the magic make sense).
EDIT: Not 100% certain what specifically you were asking in your question. This is mainly talking about pure C/C++.
A handle is a pointer or index with no visible type attached to it. Usually you see something like:
typedef void* HANDLE;
HANDLE myHandleToSomething = CreateSomething();
So in your code you just pass HANDLE around as an opaque value.
In the code that uses the object, it casts the pointer to a real structure type and uses it:
int doSomething(HANDLE s, int a, int b) {
Something* something = reinterpret_cast<Something*>(s);
return something->doit(a, b);
}
Or it uses it as an index to an array/vector:
int doSomething(HANDLE s, int a, int b) {
int index = (int)s;
try {
Something& something = vecSomething[index];
return something.doit(a, b);
} catch (boundscheck& e) {
throw SomethingException(INVALID_HANDLE);
}
}
A handle is a sort of pointer in that it is typically a way of referencing some entity.
It would be more accurate to say that a pointer is one type of handle, but not all handles are pointers.
For example, a handle may also be some index into an in memory table, which corresponds to an entry that itself contains a pointer to some object.
The key thing is that when you have a "handle", you neither know nor care how that handle actually ends up identifying the thing that it identifies, all you need to know is that it does.
It should also be obvious that there is no single answer to "what exactly is a handle", because handles to different things, even in the same system, may be implemented in different ways "under the hood". But you shouldn't need to be concerned with those differences.
In C++/CLI, a handle is a pointer to an object located on the GC heap. Creating an object on the (unmanaged) C++ heap is achieved using new and the result of a new expression is a "normal" pointer. A managed object is allocated on the GC (managed) heap with a gcnew expression. The result will be a handle. You can't do pointer arithmetic on handles. You don't free handles. The GC will take care of them. Also, the GC is free to relocate objects on the managed heap and update the handles to point to the new locations while the program is running.
This appears in the context of the Handle-Body-Idiom, also called Pimpl idiom. It allows one to keep the ABI (binary interface) of a library the same, by keeping actual data into another class object, which is merely referenced by a pointer held in an "handle" object, consisting of functions that delegate to that class "Body".
It's also useful to enable constant time and exception safe swap of two objects. For this, merely the pointer pointing to the body object has to be swapped.
A handle is whatever you want it to be.
A handle can be a unsigned integer used in some lookup table.
A handle can be a pointer to, or into, a larger set of data.
It depends on how the code that uses the handle behaves. That determines the handle type.
The reason the term 'handle' is used is what is important. That indicates them as an identification or access type of object. Meaning, to the programmer, they represent a 'key' or access to something.
HANDLE hnd; is the same as void * ptr;
HANDLE is a typedef defined in the winnt.h file in Visual Studio (Windows):
typedef void *HANDLE;
Read more about HANDLE
Pointer is a special case of handle. The benefit of a pointer is that it identifies an object directly in memory, for the price of the object becoming non-relocatable. Handles abstract the location of an object in memory away, but require additional context to access it. For example, with handle defined as an array index, we need an array base pointer to calculate the address of an item. Sometimes the context is implicit at call site, e.g. when the object pool is global. That allows optimizing the size of a handle and use, e.g. 16-bit int instead of a 64-bit pointer.