Introduction

This article explains the reason behind using pointer-to-pointer and reference-to-pointer to modify a pointer passed to a function, so as to understand their usage better. For brevity, I use the terms, ptr-to-ptr and ref-to-ptr to represent them respectively. In this article, I'm not going to discuss how to use ptr-to-ptr as a 2 dimensional array or array of pointers. Please note we can use ptr-to-ptr in both C and C++ but we can use ref-to-ptr only in C++.

Why We Need Them?

When we use "pass by pointer" to pass a pointer to a function, only a copy of the pointer is passed to the function. We can say "pass by pointer" is passing a pointer by value. In most cases, this does not present a problem. But problem comes when you modify the pointer inside the function. Instead of modifying the variable, you are only modifying a copy of the pointer and the original pointer remains unmodified, that is, it still points to the old variable. The code below demonstrates this behavior.

ppInt is the ptr-to-ptr. We will never modify this because if we do, we'll lose our grip on the address of the pointer it is pointing to.

*ppInt is the pointed pointer. If we modify this, we are modifying the contents of the pointed pointer, which is an address and in the above example, pvar. In other words, we are effectively modifying what pvar points to.

**ppInt is the dereferenced twice variable which is what pvar points to.

Syntax of Reference to Pointer

Now let us look at how you call the function with ref-to-ptr parameter

You may wonder whether, in the above func(), the parameter rpInt is pointer to reference. Just take my word for it that it is called ref-to-ptr and it is ref-to-ptr.

Let me once again summarize what all those dereferencing are,

rpInt is the reference for the pointer, pvar in the above example.

*rpInt dereferences what pvar point to, so you get the variable the pointer, pvar is pointing to.

Syntax of Tracking Reference to a Handle(C++/CLI)

Let us see how to modify a handle in C++/CLI function using the "tracking reference to a handle" parameter. This C++/CLI handle has nothing to do with Win32 HANDLEs and this handle is a reference to a managed object on the CLI heap. I use an object this time, instead of a Plain Old Data(POD)/primitive data/value type because you can only change a reference to an object.

void func(ClassA^% thObj)
{
//Modify what obj2 is referencing, to g_obj
thObj=g_obj; // g_obj is a global object.
//You can instantiate a new class
thObj=gcnew ClassA();
//Modify the variable thObj is referencing, through a its member function, SetInt().
thObj->SetInt(3);
}

thObj is the tracking reference for the handle, obj2 in the above example.

Preference of one over the other?

Now we have seen the syntax of ptr-to-ptr and ref-to-ptr. Are there any advantages of one over the other? I am afraid, no. The usage of one of both, for some programmers are just personal preferences. Some who use ref-to-ptr say the syntax is "cleaner" while some who use ptr-to-ptr, say ptr-to-ptr syntax makes it clearer to those reading what you are doing.

Do not Mistake Pointer to Pointer Arguments

Do not mistake every ptr-to-ptr arguments as purely ptr-to-ptr. An example would be when some write int main(int argc, char *argv[]) as int main(int argc, char **argv) where **argv is actually an array of pointers. Be sure to check out the library documentation first!

Reference to Pointer type (RTTI)

You cannot use RTTI to find out the type of ref-to-ptr. As typeid() does not support reference types.

Conclusion

You may ask if you would ever use ptr-to-ptr and ref-to-ptr in your projects and if it is necessary to know about them. Well, as developers, we use libraries and technologies developed by others. One example would be COM uses ptr-to-ptr to return an interface pointer using CoCreateInstance() and IUnknown::QueryInterface(). Up to some point in your developer career, you are definitely going to come across them. It is good to know them.

History

2009/04/29 Updated the explanations and added tracking reference to a handle in C++/CLI section.

C++/CLI is a managed language for C++ programmers to access the .NET framework. In C++/CLI, ^ denote a handle to a reference, % is a tracking reference. Their counterparts in native C++ is pointer(*) and reference(&). ^% is analogous to *&(reference to pointer), except that you can only use that for C++/CLI types. You can read the link below for more info.

I just spent an entire working day wrestling with a closely related problem. Yesterday, I built a structure that contains the information required to process each of six possible arguments to a character mode program. The last member is a void pointer to a location where the actual argument value goes. The reason that it is declared void is that the final, strongly typed values have varying types.

BOOL - Two of the values are stored as Boolean flags.

INT - One of the values is stored as an integer.

wchar_t - One of the values is stored as a single Unicode (wide) character.

wchar_t * - The two most challenging are pointers to strings.

While the first three types are scalars, and are easy enough to handle, the two wchar_t values cost me most of the day. After much anguish and gnashing of teeth, I arrived at a workable, if a tad brutal, solution, consisting of four assembly instructions, which I inlined into the C++ source, as follows.

On inspection, the two locations to which the pointer points contain the correct values.

One nice thing about this solution is that it works without copying anything, since the pointers point to the strings where they appear in the argument list; that is, each string pointer points to the correct element in the argV[] array.

The other nice thing about this solution is that, since the code that does all the pointing is written in assembly language, which is pretty blase about types, I could dispense with the reinterpret_cast operator that would otherwise have been required.

When the program is completed, I expect to develop an article about the table driven command line argument parser.

Hi, this is great article, really helpful to understand PTP and RTP! Thank you for posting this!
Still I have a question, about returning pointer method.
Using this method, how do you implement func() and main() which perform same as the functions when you used to explain pointer to pointer or reference to pointer?
I couldn't understand the part you used "return new int", and why it can be alternative for PTP and RTP methods.
Thank you so much for your help in advance!

As you said: "If you find that the ptr-to-ptr and ref-to-ptr syntax are rather hard to understand, you can just use the "return the pointer" method." In return the pointer method, can we return 2 pointers after modifying them in the function?

I'm recently learning C#. In C# you can pass parameters by value or by reference, and as you know, there are value types and reference types in C#.

I don't know if reference in C# means the same thing as in C++. But I think passing a reference type by reference in C# is similar to passing a pointer "by reference" in C++ (Reference to Pointer). As in both cases, the callee can change the values of the object’s state data as well as the object the ref type/pointer is referencing/pointing to.

I am terribly sorry for the late reply as I was rushing for my open source library and its article: Outline Text[^]

You are right in saying that "passing a reference type by reference in C# is similar to passing a pointer "by reference" in C++ (Reference to Pointer). As in both cases, the callee can change the values of the object’s state data as well as the object the ref type/pointer is referencing/pointing to."

As for the Swap definition, you cannot define the parameters in parenthesis in C/C++.

As for the Java question, I do not know much about Java to comment on it. In other words, I do not have a swap solution for Java, as you have said Java pass parameters by value. Let's hope the upcoming Java 7 has some features which address this 'deficiency'.

You might be interested to know that I got a C/C++ programming job, 5 years ago because of this ptr-to-ptr article. The manager told me that many C/C++ programmers after 10 years of C/C++ programming, still do not know pointers are passed by value, which means a copy of it is passed. The manager was impressed by my C knowledge. Perhaps, you would like to read the article in detail if you haven't done so. Thanks for commenting.