Click here to Skip to main content
13,351,050 members (54,549 online)
Click here to Skip to main content
Add your own
alternative version

Stats

826.2K views
376 downloads
135 bookmarked
Posted 12 Apr 2016

Pointer to Pointer and Reference to Pointer

, 11 Jan 2018
Rate this:
Please Sign up or sign in to vote.
Explains the reason behind using pointer-to-pointer and reference-to-pointer to modify a pointer passed to a function.

Contents

Introduction
Why We Need Them?
Syntax of Pointer to Pointer
Syntax of Reference to Pointer
Syntax of Returning Pointer
Syntax of Returning Reference
Preference of one over the other?
Do not Mistake Pointer to Pointer arguments
Reference to Pointer type (RTTI)
Conclusion
History

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.

int g_n = 42;

void example_ptr()
{
    int n = 23;
    int* pn = &n;

    std::cout << "example_ptr()" << std::endl;

    std::cout << "Before :" << *pn << std::endl; // display 23

    func_ptr(pn);

    std::cout << "After :" << *pn << std::endl; // display 23
}

void func_ptr(int* pp)
{
    pp = &g_n;
}

This is not a problem with C/C++ only. This is exactly same case with Python. In example below where a dictionary, instruments, is initialized again in fill_up method. After the method call, instruments is still empty. Because only a copy of instruments is passed to fill_up. You can think of instruments as pointer which is passed by copy. The initializing code is like calling C++ new to instantiate the dictionary. instruments inside fill_up points to new memory while the outer one still points to original memory. Underneath the surface, computer languages makes use of address to load and fetch data. There is no escape from using address underlyingly, even in Python, a language which does not support pointer and address. In Java, reference are disguised pointer or indirect pointer, with meta information, which is dereferenced automatically, whose address is updated after garbage collection.

#!/usr/bin/python

def fill_up(instruments):
    instruments = {} # This line caused the problem
    instruments["1"] = 1

instruments = {}
fill_up(instruments)
print "len(instruments):%d" % len(instruments)

Output shows instruments has zero elements after the call.

len(instruments):0

Initialization is removed in the below code.

#!/usr/bin/python

def fill_up(instruments):
    instruments["1"] = 1

instruments = {}
fill_up(instruments)
print "len(instruments):%d" % len(instruments)

Now output shows instruments length correctly!

len(instruments):1

Syntax of Pointer to Pointer

This is how you call the function with ptr-to-ptr parameter.

int g_n = 42;

void example_ptr_to_ptr()
{
    int n = 23;
    int* pn = &n;

    std::cout << "example_ptr_to_ptr()" << std::endl;

    std::cout << "Before :" << *pn << std::endl; // display 23

    func_ptr_to_ptr(&pn);

    std::cout << "After :" << *pn << std::endl; // display 42
}

void func_ptr_to_ptr(int** pp)
{
    *pp = &g_n;
}

Syntax of Reference to Pointer

Now let us look at how you call the function with ref-to-ptr parameter. Many C++ developers mistook this type as pointer to reference. C++ types are inferred by reading from right to left!.

int g_n = 42;

void example_ref_to_ptr()
{
    int n = 23;
    int* pn = &n;

    std::cout << "example_ref_to_ptr()" << std::endl;

    std::cout << "Before :" << *pn << std::endl; // display 23

    func_ref_to_ptr(pn);

    std::cout << "After :" << *pn << std::endl; // display 42
}

void func_ref_to_ptr(int*& pp)
{
    pp = &g_n;
}

 

Syntax of Returning Pointer

Or you can just simply return the pointer.

int g_n = 42;

void example_ret_ptr()
{
    int n = 23;
    int* pn = &n;

    std::cout << "example_ret_ptr()" << std::endl;

    std::cout << "Before :" << *pn << std::endl; // display 23

    pn = func_ret_ptr();

    std::cout << "After :" << *pn << std::endl; // display 42
}

int* func_ret_ptr()
{
    return &g_n;
}

Syntax of Returning Reference

Or you can just simply return the reference.

int g_n = 42;

void example_ret_ref()
{
    int n = 23;
    int* pn = &n;

    std::cout << "example_ret_ref()" << std::endl;

    std::cout << "Before :" << *pn << std::endl; // display 23

    pn = &func_ret_ref();

    std::cout << "After :" << *pn << std::endl; // display 42
}

int& func_ret_ref()
{
    return g_n;
}

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.

void test(int*& rpInt)
{
  std::cout << "type of *&rpInt: " << typeid(rpInt).name() 
    << std::endl;//will show int *

}

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

  • 2018/01/11 Add links to show C++ types are inferred by reading from right to left, so as to show *& is reference to pointer, not pointer to reference.
  • 2017/08/23 Show Python code which has the same problem as C++.
  • 2016/10/02 Simpler examples
  • 2009/04/29 Updated the explanations and added tracking reference to a handle in C++/CLI section.
  • 2003/09/01 First release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Cake Processor
Software Developer (Senior)
United States United States
C++ developer transitioning to Python

Semi-retired from writing articles but may contribute tips from time to time.

Lean Programmer Blog

IT Certifications

  • IT Infrastructure Library Foundational (ITIL v3)
  • Scrum Alliance Certified Scrum Master (CSM)
  • Certified Secure Software Lifecycle Professional (CSSLP)

View my certificates here.

You may also be interested in...

Comments and Discussions

 
GeneralRe: Return the pointer method Pin
Member 98347545-Mar-13 1:09
memberMember 98347545-Mar-13 1:09 
GeneralMy vote of 5 Pin
Morph King22-Sep-12 4:55
memberMorph King22-Sep-12 4:55 
GeneralMy vote of 5 Pin
Anitesh Kumar24-May-12 21:29
memberAnitesh Kumar24-May-12 21:29 
GeneralMy vote of 5 Pin
pradhan cn10-Sep-11 14:06
memberpradhan cn10-Sep-11 14:06 
GeneralMy vote of 5 Pin
Member 724777616-Aug-10 1:23
memberMember 724777616-Aug-10 1:23 
Generalref-to-ptr problem Pin
danhass3-Mar-10 11:36
memberdanhass3-Mar-10 11:36 
Generalpass-by-pointer Pin
zired18-Dec-09 3:56
memberzired18-Dec-09 3:56 
GeneralRe: pass-by-pointer Pin
Shao Voon Wong2-Feb-10 22:39
memberShao Voon Wong2-Feb-10 22:39 
Hi zired,

In your example, after the func call, pvar is still pointing to nvar and now nvar holds 1, instead of the original value, 2. pvar is supposed to change to point to g_One, after the func call.

Please kindly approach me if you are unclear or still have any other questions.

Thanks for asking.
Generalpass-by-pointer Pin
zired18-Dec-09 3:55
memberzired18-Dec-09 3:55 
Questionsome questions about "reference to pointer" Pin
lhyblue18-Sep-09 4:10
memberlhyblue18-Sep-09 4:10 
AnswerRe: some questions about "reference to pointer" Pin
Shao Voon Wong28-Sep-09 16:13
memberShao Voon Wong28-Sep-09 16:13 
GeneralMy vote of 2 Pin
Country Man4-May-09 23:22
memberCountry Man4-May-09 23:22 
GeneralRe: My vote of 2 Pin
Shao Voon Wong28-Sep-09 16:20
memberShao Voon Wong28-Sep-09 16:20 
Generalwhy not using memcpy Pin
auralius18-Jan-09 14:42
memberauralius18-Jan-09 14:42 
GeneralRe: why not using memcpy Pin
Wong Shao Voon19-Jan-09 15:17
memberWong Shao Voon19-Jan-09 15:17 
GeneralRe: why not using memcpy Pin
auralius22-Jan-09 20:03
memberauralius22-Jan-09 20:03 
GeneralRe: why not using memcpy Pin
Wong Shao Voon27-Jan-09 17:49
memberWong Shao Voon27-Jan-09 17:49 
GeneralReference to a pointer and typing. Pin
David G Hunt22-Sep-08 12:48
memberDavid G Hunt22-Sep-08 12:48 
Generalvery nice article, Pin
morten4129-Oct-07 4:59
membermorten4129-Oct-07 4:59 
GeneralRe: very nice article, Pin
Wong Shao Voon29-Oct-07 18:24
memberWong Shao Voon29-Oct-07 18:24 
GeneralRe: very nice article, Pin
morten4130-Oct-07 2:14
membermorten4130-Oct-07 2:14 
QuestionThanks for it, but how to get it to work in .NET 2005 Pin
MausOnMars16-Oct-07 0:30
memberMausOnMars16-Oct-07 0:30 
AnswerRe: Thanks for it, but how to get it to work in .NET 2005 Pin
Wong Shao Voon16-Oct-07 0:40
memberWong Shao Voon16-Oct-07 0:40 
GeneralRe: Thanks for it, but how to get it to work in .NET 2005 Pin
MausOnMars16-Oct-07 0:57
memberMausOnMars16-Oct-07 0:57 
GeneralRe: Thanks for it, but how to get it to work in .NET 2005 Pin
Wong Shao Voon16-Oct-07 4:41
memberWong Shao Voon16-Oct-07 4:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.180111.1 | Last Updated 11 Jan 2018
Article Copyright 2016 by Cake Processor
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid