Pointer to Pointer in C

Pointer to Pointer in C. Pointer to Pointer in C Tutorial. Learn Pointer to Pointer in C
Pointer to Pointer in C

What is Pointer to Pointer in C ?

In C programming, a pointer to a pointer, also known as a “double pointer,” is a variable that holds the address of another pointer variable. It is used to create multiple levels of indirection or to indirectly access and modify a pointer variable.

The main purpose of using a pointer to a pointer is to enable dynamic memory allocation and manipulation, especially when dealing with complex data structures like linked lists, trees, or multidimensional arrays. It allows for the modification of a pointer from a different function or context, which can be useful in certain scenarios.

To understand how a pointer to a pointer works, let’s break it down step by step:

1. Declaration: To declare a pointer to a pointer, you need to use the ** notation. Here’s an example:

int **pp;

2 Initialization: After declaring a pointer to a pointer, you can initialize it by assigning the address of another pointer to it. This can be done using the & operator. Here’s an example:

int *p;
int **pp;
p = &someVariable;
pp = &p;

3. Accessing the value: To access the value stored in the variable pointed to by a pointer to a pointer, you need to use the * operator twice. Here’s an example:

int value = **pp;

In above example, **pp dereferences the first pointer to get the second pointer (p), and then dereferences the second pointer to get the value stored in someVariable.

4. Modifying the value: To modify the value stored in the variable pointed to by a pointer to a pointer, you also need to use the * operator twice. Here’s an example:

**pp = newValue;

In above example, **pp dereferences the first pointer to get the second pointer (p), and then dereferences the second pointer to modify the value stored in someVariable to newValue.

Examples of Pointer to Pointer:

1. Dynamic Memory Allocation:

int **matrix;
int rows = 3;
int cols = 3;
matrix = (int **)malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
    matrix[i] = (int *)malloc(cols * sizeof(int));
}

In above example, we allocate memory for a 2D matrix using a pointer to a pointer. The matrix variable is a pointer to a pointer that will hold the address of each row in the matrix. By using a double pointer, we can dynamically allocate memory for each row.

2. Swapping Pointers:

void swap(int **ptr1, int **ptr2) {
    int *temp = *ptr1;
    *ptr1 = *ptr2;
    *ptr2 = temp;
}

int main() {
    int a = 10;
    int b = 20;
    int *p1 = &a;
    int *p2 = &b;
    swap(&p1, &p2);
    // Now p1 points to 20 and p2 points to 10
    return 0;
}

In above example, the swap function takes two pointers to pointers as arguments. Inside the function, the addresses stored in the pointers are swapped using a temporary pointer variable. This allows us to swap the values that the pointers point to.

3. Linked List Manipulation:

struct Node {
    int data;
    struct Node *next;
};

void insert(struct Node **head, int data) {
    struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = *head;
    *head = newNode;
}

int main() {
    struct Node *list = NULL;
    insert(&list, 10);
    insert(&list, 20);
    // Now list points to the first node of the linked list
    return 0;
}

In above example, we have a linked list implementation. The insert function takes a pointer to a pointer to the head of the list. By passing the address of the list pointer (&list), we can modify the head pointer of the list and insert new nodes at the beginning.

More: