Difference Between *& and **& in C++

In C++, the *& (pointer to reference) and **&(pointer to pointer reference) symbols are used in the context of pointers and references for manipulating memory addresses and dealing with complex data structures. While they seem similar, they serve different purposes. In this article, we will learn the difference between *& and **& in C++.

C++ Pointer to Reference( *& )

The *& symbol also called reference pointer is a combination of a pointer and a reference that is used to declare a pointer to a reference. The * symbol is used to declare a pointer, and the & symbol is used to get the address of a variable thus it creates a reference that point to the value stored by a pointer.

Syntax to Declare Reference Pointer in C++

dataType*& referenceName = pointerVariable;

Here, ptrVariable is a pointer to a variable and referenceName is the name of a pointer to reference.

Example

The below example demonstrates how we can declare and use the pointer to reference in C++.

C++
// C++ program to demonstrate the use of pointer to
// reference

#include <iostream>
using namespace std;

// Function to modify the pointer
void modifyPointer(int*& refPtr)
{
    // Allocating new memory
    static int newNumber = 99;
    refPtr = &newNumber;
}

int main()
{
    // define a variable x
    int x = 5;
    // declare a pointer to variable x
    int* ptr = &x;

    cout << "Original pointer points to value: " << *ptr
         << endl;

    // Pass the pointer to the function by reference
    modifyPointer(ptr);

    // Now ptr should point to the newNumber in
    // modifyPointer
    cout << "Pointer now points to value: " << *ptr << endl;

    return 0;
}

Output
Original pointer points to value: 5
Pointer now points to value: 99

C++ Pointer to Pointer Reference (** & )

The **& symbol also called pointer to pointer reference(double pointer) is used to declare a pointer to a pointer. The ** symbol is used to declare a pointer to a pointer, and the & symbol is used to get the address of a pointer. It is mainly used for handling complex cases like multiple levels of indirection or managing dynamic memory allocation.

Syntax to Declare Pointer to Pointer Reference in C++

dataType**& referenceName = pointerToPointerVariable;

Here, pointerToPointerVariable is a pointer to pointer that stores the address a variable and referenceName is a name of pointer to pointer reference.

Example

The below example demonstrates how we can declare and use the pointer to pointer reference in C++.

C++
// C++ program to demonstrate the use of pointer to pointer
// reference

#include <iostream>
using namespace std;

// Function to modify the pointer to point to a different
// integer
void modifyPointer(int**& refToPtrPtr)
{
    static int newValue = 42;
    *refToPtrPtr = &newValue;
}

int main()
{

    // declare a variable x
    int x = 10;
    // declare a pointer to variable x
    int* ptr = &x;

    // Printing the original value pointed by ptr
    cout << "Original value pointed by ptr: " << *ptr
         << endl; 

    // Declare a reference to the pointer to pointer
    int** ptrRef = &ptr;

    // Call function to modify the pointer through the
    // pointer to pointer reference
    modifyPointer(ptrRef);

    // Printing the new value pointed by ptr after
    // modification
    cout << "New value pointed by ptr: " << *ptr
         << endl; 

    return 0;
}

Output
Original value pointed by ptr: 10
New value pointed by ptr: 42

Difference Between *& and **& in C++

The below table illustrates the key differences between *& and **& in C++.

Feature

*& (Pointer to Reference)

**& (Pointer to Pointer Reference)

Definition

*& combines a pointer and a reference, allowing us to dereference a pointer and then immediately take a reference to the resulting value.

**& refers to a reference to a pointer to another pointer, allowing deep manipulation of pointer chains.

Syntax

int* ptr = & value;

int**& ref = ptrPtr;

Usage

It is used to modify the value at the pointer’s location indirectly through a reference in functions or complex data structures.

It is used to modify the address stored in a pointer or the pointer via itself, commonly used in dynamic and complex data manipulations.

Memory Access

It allows manipulation of the value pointed by the pointer, but not the address in the pointer.

It enables control over the address in a pointer and the value at that address, providing deeper manipulation capabilities.

Common Use

It is commonly used in scenarios where the value needs to be changed without modifying the pointer itself, like function calls where values need to be updated.

It is commonly used in scenarios requiring reassignment or reallocation of memory structures, such as modifying linked lists or dynamic arrays.

Effect on Pointed Data

It allows for direct modification of the data at the memory address pointed to, without affecting the pointer’s address.

It allows modification of the pointer’s address (i.e., where the pointer is pointing) and the data at the new address.