SatView: Pointer Perfect, Part 2: Construction / Destruction - Pointer Pointers
(Page 4 of 4 )
So a pointer is a variable that stores an address and can be null. This means that a pointer can store the address to another pointer. That’s right: a pointer to a pointer.
If the term pointer pointers sounds exotic to you, don’t worry. You have been using them all along:
int main(int argc, char *argv[]) { return 0; }
See, you have been using them all the time! Argv is a pointer to an array of char and could have been written as char **argv (main is written many different ways, actually). If you define an array char arry[25]; then arry can be used and seen as a char* simply because an array points to the address of the first element; thus argv is a pointer to a char*. You can roughly translate argv as a list of a list of characters.
Using the techniques we already know we can create pointer pointers expanding on the first example from Part 1:
int main(int argc, char *argv[]) {
int myVar = 10;
int *pPtr = &myVar;
int *ppPtr = &pPtr;
return 0;
}
Again we compile it and gaze at it in the debugger:
0x0012FEB8 cccccccc ÌÌÌÌ
0x0012FEBC 0012fec8 Èþ.. ppPtr addr:0x0012FEBC value:0x0012FEC8
0x0012FEC0 cccccccc ÌÌÌÌ
0x0012FEC4 cccccccc ÌÌÌÌ
0x0012FEC8 0012fed4 Ôþ.. pPtr addr:0x0012FEC8 value:0x0012FED4
0x0012FECC cccccccc ÌÌÌÌ
0x0012FED0 cccccccc ÌÌÌÌ
0x0012FED4 0000000a .... myVar addr:0x0012FED4 value:10
0x0012FED8 cccccccc ÌÌÌÌ
You can see that ppPtr holds the address to pPtr (0x0012FEC8), which holds the address to myVar (0x0012FED4). The concept holds!
Let's take a little sidestep here. If you were not allowed to use references, but would like to return a value via a function parameter, how would you do it? Here is a function declaration that returns a boolean value to tell you whether the function succeeded or not and a counter:
bool foo(int *count);
By passing the address of an int variable you declared before calling the function, a result can be returned from inside the function by assigning a value to be held at that address. What if you want to return an address to something that is much larger than a primitive? Then you can use pointer pointers. Use them when a function wants to return the address to a dynamically allocated piece of memory through one of its function parameters. (COM actually forces you to do it this way, since pointers are capable of crossing programming language barriers and C++ references not.)
Since functions in COM always return HRESULT, the only way to return a polymorphic object (e.g. the pointer to the base class of a newly created derived object) is by storing that pointer in a pointer that can hold it:
HRESULT foo (MyBaseClass **newObj);
In the foo function you can create a new MyBaseClass inside the newObj pointer pointer:
*newobj = reinterpret_cast<MyBaseClass*>(new MyDerivedClass);
Pointer arithmetic combined with pointer pointers allow you to do some pretty nifty things. If we assume pMem to be a character pointer to a piece of memory that was read binary from a file and pOffset a character pointer to some memory that contains the offsets of objects inside that file, you could calculate pMem to certain offsets with the following statement (using C-style casting on purpose to maintain readability):
*((char **)(&pMem))=((char *)((unsigned int)pOffset)+((unsigned int)pMem));
There are better ways to construct binary file formats, but this one shows nicely how complicated the use of pointers can become. Next time we will look at smart pointers; C++ classes that help you manage all these crazy pointers.
| DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware. |