🌐
GeeksforGeeks
geeksforgeeks.org › c language › c-pointer-to-pointer-double-pointer
C - Pointer to Pointer (Double Pointer) - GeeksforGeeks
It is also known as a pointer to a pointer because it points to another pointer instead of directly pointing to a variable. The first pointer stores the address of a variable, while the double pointer stores the address of that first pointer.
Published: July 18, 2026
🌐
Reddit
reddit.com › r/learnprogramming › i don't understand double pointers in c
r/learnprogramming on Reddit: I don't understand double pointers in C
September 9, 2020 -

So I understand pointers. An int * would point to the address of an integer. I understand how you could have a struct pointer and all that. I even sort of understand double pointers. An int ** would be a pointer, pointing to another pointer, which is pointing to an integer. I think that's right but I could be wrong. It's just when I see it in code my brain has a hard time grasping it. I'm looking at a past lab from a course to try to understand it, and I just don't really get it.

So in the lab we were given a struct student, which in itself has two pointer variables among others. We have to read in a file, with the first line containing three integers. The first is the number of courses, C. The next integer is N, which is the number of students per course. In the code, they do fscanf to take in the first few integers. I understand that. Then they allocate memory for courses using calloc.

The line is: student** courses = calloc(*C, sizeof(student*));

This is all inside a function which returns another student**. This is where I get lost. A struct double pointer still is hard for me to grasp. My friend said it's like an array of structs, but I still don't really get it.

Maybe if someone could explain them, or give me a resource that will explain them I would really appreciate it.

Top answer
1 of 3
2
Here's the critical piece of information you need to reason about pointers. A pointer is a variable that holds an address. That's it. That's all you need to know. From there you should be able to reason about anything pointer related. It will still be mind bendy for a time, but always start there. int i = 42; This is a variable that holds an integer. No problem. int *p = &i; This is a variable that holds an address. Specifically an address of an integer, but don't really worry about that. Just remember, it's an address. int **double_p = &p; This is also a variable that holds an address. The only difference is what it holds an address of. It holds the address of the variable p. p holds an address of an int. student** courses = calloc(*C, sizeof(student*)); To help understand this, take a step back for a moment. int *foo = calloc(16, sizeof(int)); foo holds the address of an int. calloc sets aside enough memory for 16 ints, and then returns the address of the "zeroth" element of that dynamically allocated array. foo then holds the address of the start of that array. OK, now back to the confusing line of code. student** courses = calloc(*C, sizeof(student*)); courses holds an address. The type of data at that address? Another pointer, specifically, a pointer to a student struct. So, calloc will set aside enough memory for an array to hold a bunch of memory addresses. calloc is going to return the address of the "zeroth" element of that array. Each element of that array will be able to hold a memory address of a student struct.
2 of 3
1
A pointer can be thought of as a reference to something else by specifying the location of that thing. If you want to deliver a package to my house, you aren’t going to ask me to bring my house to you because that’s silly. Instead, you ask me for the address of my house and then you go to that address and drop off the package. You have to dereference (go to an address) just once to get to the house, so this is a single pointer. A pointer to a pointer is the same thing, just with another reference layer. I don’t want anyone to overhear where my house is, so instead of telling you it’s address directly, I write the address on a piece of paper and I hide it somewhere. I then tell you where to find the piece of paper. To get to my house, you first have to go to the paper’s address, read it, then go to the address that’s written on it. You have to dereference twice in order to get to the house, so this is a double pointer.
Please help !! what are double pointers used for ? Apr 3, 2016
r/C_Programming
10y ago
Two Pointers Pattern : r/csMajors Jun 9, 2022
r/csMajors
4y ago
[C] De-referencing a double pointer Dec 27, 2019
r/C_Programming
6y ago
How pointers ACTUALLY work? (CS noob question) Jul 22, 2023
r/cpp_questions
3y ago
Tips/Guides on pointers Dec 10, 2023
r/C_Programming
2y ago
More results from reddit.com
Discussions

Double pointer C/C++ - Stack Overflow
Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... Save this question. Show activity on this post. ... Closed 4 years ago. can someone explain to me how double pointers work? More on stackoverflow.com
🌐 stackoverflow.com
c - Why use double indirection? or Why use pointers to pointers? - Stack Overflow
When should a double indirection be used in C? Can anyone explain with a example? What I know is that a double indirection is a pointer to a pointer. Why would I need a pointer to a pointer? More on stackoverflow.com
🌐 stackoverflow.com
c - usage of double pointers and n pointers? - Software Engineering Stack Exchange
Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... I am familiar with basic C pointers. Just wanted to ask what is the actual use of double pointers or for that matter n pointer? More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
June 26, 2014
What is the point of a double pointer in c/c++?
They are not "double pointers", and thinking of them as such will obscure their purpose; they are "pointers to pointers". More on reddit.com
🌐 r/learnprogramming
11
1
July 9, 2017
🌐
DEV Community
dev.to › noah11012 › double-pointers-in-cc-2n96
Double Pointer C: Double Pointers in C/C++ - DEV Community
January 12, 2019 - When dereferencing a double pointer, we do not get the final object, but what is expected: a pointer that must be dereferenced one more time to retrieve the final value. It would be similar to the code below. int *ptr = *value_double_ptr; int final_value = *ptr;
🌐
MYCPLUS
mycplus.com › home › programming
Double Pointer in C (Pointer to Pointer): Guide + Examples
February 10, 2021 - ... A double pointer (pointer to pointer) is a pointer variable that stores the address of another pointer. Declared with two asterisks — int **pptr; — it adds one more level of indirection: pptr holds the address of a pointer, *pptr gives ...
🌐
EDUCBA
educba.com › home › software development › software development tutorials › c programming tutorial › double pointer in c
Double Pointer in C | How does Double Pointer work in C with Examples
April 1, 2023 - Whereas pointer to pointer which means a pointer stores the address of another pointer, and this second pointer will be storing the address of the previous or first pointer which is also known as double-pointer in C.
Address: Unit no. 202, Jay Antariksh Bldg, Makwana Road, Marol, Andheri (East),, 400059, Mumbai
🌐
Scaler
scaler.com › home › topics › c – pointer to pointer (double pointer)
C – Pointer to Pointer (Double Pointer) - Scaler Topics
October 10, 2023 - Similar to how a pointer variable ... a memory address. So, using a pointer to the pointer aka a double pointer in C, we can make the previous pointer point to another memory location....
🌐
Codecademy
codecademy.com › docs › pointers › double pointer
C | Pointers | Double Pointer | Codecademy
May 29, 2025 - In C, a double pointer is a pointer that holds the memory address of another pointer.
Find elsewhere
🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_pointer_to_pointer.htm
Pointer to Pointer (Double Pointer) in C
A pointer to pointer which is also known as a double pointer in C is used to store the address of another pointer. A variable in C that stores the address of another variable is known as a pointer.
🌐
Medium
medium.com › @muirujackson › use-of-double-pointers-in-c-d94e086a13fc
Use of Double Pointers in C?. In C, we use pointers to hold memory… | by Muiru Jackson | Medium
April 28, 2023 - To access the data at that address, we dereference the pointer by using the * operator. A double pointer, or a pointer-to-pointer, is a pointer variable that holds the address of another pointer variable.
Top answer
1 of 4
7

Let's draw out:

int q = 15;
int * p = &q;
int * * z = &p;

            q   
          +----+  
    p --> | 15 |  
    ^     +----+  
    |  
    z  

In the above drawing, q is an integer variable with the value 15.
The pointer p points to the variable q.
The pointer z points to the pointer p.

The expression *z refers to the value in the pointer p.
The expression **z or rewritten as *(*z) refers to the variable q (following the links).

We know that (*z) is the pointer p, so let's replace:
*(*z) == *(p);

We can replace *(p) with q, from the above definitions: *(*z) == *(p) == q;.

2 of 4
6

Let's fully draw it out:

int anArray[] = {5,16,33,99};  // 4 values in consecutive addresses

//            ----
// anArray ->   5
//            ----
//             16
//            ----
//             33
//            ----
//             99
//            ----

int * p = anArray; // A new variable, whose contents points to the address of anArray

//            ---------
// anArray ->   5       <-+
//            ---------   |
//             16         |
//            ---------   |
//             33         |
//            ---------   |
//             99         |
//            ---------   |
//       p ->  anArray   -+
//            ---------

printf("*p = %d\n", *p);  // prints 5
p++;                      // increment pointer p to the next element.

//            -----------
// anArray ->   5      
//            -----------
//             16         <-+
//            -----------   |
//             33           |
//            -----------   |
//             99           |
//            -----------   |
//       p ->  anArray+1   -+
//            ---------

printf("Now *p = %d\n", *p); // prints 16
int * q = &anArray[3];       // new pointer variable, points to 4th element of anArray (0-based)

//            -----------
// anArray ->   5      
//            -----------
//             16         <-+
//            -----------   |
//             33           |
//            -----------   |
//             99           | <-+
//            -----------   |   |
//       p ->  anArray+1   -+   |
//            -----------       |
//       q ->  anArray+3   -----+
//            -----------

int ** x = &q;  // new pointer variable, points to address of q pointer variable

//            -----------
// anArray ->   5      
//            -----------
//             16         <-+
//            -----------   |
//             33           |
//            -----------   |
//             99           | <-+
//            -----------   |   |
//       p ->  anArray+1   -+   |
//            -----------       |
//       q ->  anArray+3   -----+ <-+
//            -----------           |
//       x ->  q           ---------+
//            -----------

**x = 12;  // get address in x (q), then address in q (anArray+3) and write 12 to it

//            -----------
// anArray ->   5      
//            -----------
//             16         <-+
//            -----------   |
//             33           |
//            -----------   |
//             12           | <-+
//            -----------   |   |
//       p ->  anArray+1   -+   |
//            -----------       |
//       q ->  anArray+3   -----+ <-+
//            -----------           |
//       x ->  q           ---------+
//            -----------

*x = p;  // get address in x (q) and write p value to it (anArray+1)

//            -----------
// anArray ->   5      
//            -----------
//             16         <-+ <-+
//            -----------   |   |
//             33           |   |
//            -----------   |   |
//             12           |   |
//            -----------   |   |
//       p ->  anArray+1   -+   |
//            -----------       |
//       q ->  anArray+1   -----+ <-+
//            -----------           |
//       x ->  q           ---------+
//            -----------

**x = 42;  // get address in x (q), then address in q (anArray+1) and write a 42 to it

//            -----------
// anArray ->   5
//            -----------
//             42         <-+ <-+
//            -----------   |   |
//             33           |   |
//            -----------   |   |
//             12           |   |
//            -----------   |   |
//       p ->  anArray+1   -+   |
//            -----------       |
//       q ->  anArray+1   -----+ <-+
//            -----------           |
//       x ->  q           ---------+
//            -----------

q[1] = 9;  // get address in q (anArray+1) add one element (anArray+2), and assign 9

//            -----------
// anArray ->   5      
//            -----------
//             42         <-+ <-+   (q[0])
//            -----------   |   |
//              9           |   |   (q[1])
//            -----------   |   |
//             12           |   |
//            -----------   |   |
//       p ->  anArray+1   -+   |
//            -----------       |
//       q ->  anArray+1   -----+ <-+
//            -----------           |
//       x ->  q           ---------+
//            -----------
🌐
Codedamn
codedamn.com › news › c programming
What are double pointers in C?
March 10, 2024 - Each pointer occupies a memory address, and a double pointer stores the address of a first-level pointer, which in turn points to the actual data or another pointer. The concept of double pointers as pointing to pointers is fundamental to ...
🌐
BeginnersBook
beginnersbook.com › 2014 › 01 › c-pointer-to-pointer
C – Pointer to Pointer (Double Pointer) with example
We already know that a pointer holds the address of another variable of same type. When a pointer holds the address of another pointer then such type of pointer is known as pointer-to-pointer or double pointer. In this guide, we will learn what is a double pointer, how to declare them and how ...
🌐
Joequery
joequery.me › notes › double-pointers-c
Introduction to double pointers in C - part 1 | JoeQuery
So we've seen that double pointers operate identically to basic pointers in regards to taking the address of a variable. But what about dereferencing a double pointer? Recall that *(&x) == x. ... What would the program output if we were to print out the value of **pp? Let's form some expressions using our fact *(&x) == x. Thus the claim implied by working through these expressions is **pp (described as "the double dereference of pp") is equivalent to the variable x for our example above.
Top answer
1 of 16
586

If you want to have a list of characters (a word), you can use char *word

If you want a list of words (a sentence), you can use char **sentence

If you want a list of sentences (a monologue), you can use char ***monologue

If you want a list of monologues (a biography), you can use char ****biography

If you want a list of biographies (a bio-library), you can use char *****biolibrary

If you want a list of bio-libraries (a ??lol), you can use char ******lol

... ...

yes, I know these might not be the best data structures


Usage example with a very very very boring lol

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int wordsinsentence(char **x) {
    int w = 0;
    while (*x) {
        w += 1;
        x++;
    }
    return w;
}

int wordsinmono(char ***x) {
    int w = 0;
    while (*x) {
        w += wordsinsentence(*x);
        x++;
    }
    return w;
}

int wordsinbio(char ****x) {
    int w = 0;
    while (*x) {
        w += wordsinmono(*x);
        x++;
    }
    return w;
}

int wordsinlib(char *****x) {
    int w = 0;
    while (*x) {
        w += wordsinbio(*x);
        x++;
    }
    return w;
}

int wordsinlol(char ******x) {
    int w = 0;
    while (*x) {
        w += wordsinlib(*x);
        x++;
    }
    return w;
}

int main(void) {
    char *word;
    char **sentence;
    char ***monologue;
    char ****biography;
    char *****biolibrary;
    char ******lol;

    //fill data structure
    word = malloc(4 * sizeof *word); // assume it worked
    strcpy(word, "foo");

    sentence = malloc(4 * sizeof *sentence); // assume it worked
    sentence[0] = word;
    sentence[1] = word;
    sentence[2] = word;
    sentence[3] = NULL;

    monologue = malloc(4 * sizeof *monologue); // assume it worked
    monologue[0] = sentence;
    monologue[1] = sentence;
    monologue[2] = sentence;
    monologue[3] = NULL;

    biography = malloc(4 * sizeof *biography); // assume it worked
    biography[0] = monologue;
    biography[1] = monologue;
    biography[2] = monologue;
    biography[3] = NULL;

    biolibrary = malloc(4 * sizeof *biolibrary); // assume it worked
    biolibrary[0] = biography;
    biolibrary[1] = biography;
    biolibrary[2] = biography;
    biolibrary[3] = NULL;

    lol = malloc(4 * sizeof *lol); // assume it worked
    lol[0] = biolibrary;
    lol[1] = biolibrary;
    lol[2] = biolibrary;
    lol[3] = NULL;

    printf("total words in my lol: %d\n", wordsinlol(lol));

    free(lol);
    free(biolibrary);
    free(biography);
    free(monologue);
    free(sentence);
    free(word);
}

Output:

total words in my lol: 243
2 of 16
227

One reason is you want to change the value of the pointer passed to a function as the function argument, to do this you require pointer to a pointer.

In simple words, Use ** when you want to preserve (OR retain change in) the Memory-Allocation or Assignment even outside of a function call. (So, Pass such function with double pointer arg.)

This may not be a very good example, but will show you the basic use:

#include <stdio.h>
#include <stdlib.h>

void allocate(int **p)
{
    *p = (int *)malloc(sizeof(int));
}

int main()
{
    int *p = NULL;
    allocate(&p);
    *p = 42;
    printf("%d\n", *p);
    free(p);
}
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 177796-double-pointers-c.html
Double pointers - C
June 24, 2019 - Hi everybody, I'm learning C language (actually it's better to say that I'm trying to learn it), and I have some difficulties with the use of double pointers. I give you an example here: //BEGINNING OF THE CODE int a=5; int b=2; int *point; int **doublepointer; pointer=&a; /*FIRST QUESTION: now 'pointer' is equal to the adress of 'a', and '*pointer' is equal to the value of 'a' .
🌐
Medium
medium.com › @suryabhagavanchakkapalli › double-pointers-in-c-understanding-pointers-to-pointers-a35bdca25fa3
DSA in C- Part5: Double Pointers in C — Understanding Pointers to Pointers | by Bhagavan | Medium
March 10, 2026 - Therefore, modifying that pointer inside the function will not affect the original pointer. To modify the original pointer, we must pass the address of the pointer, which means we must use a double pointer.
🌐
Medium
medium.com › @acamvproducingstudio › c-programming-double-pointers-and-function-pointers-a99c2687fa3a
C Programming — Double Pointers and Function Pointers | by Ac Studio | Medium
May 25, 2026 - So, how do we define a double pointer? We know that a pointer to an integer is int *ptr. The way we define a pointer is by adding a * after the type we want to point to. Therefore, a pointer pointing to an integer pointer can be written as int **ptr.
🌐
Sanfoundry
sanfoundry.com › c-tutorials-double-pointer
Double Pointer in C (Pointer to Pointer) - Sanfoundry
December 31, 2025 - This C Tutorial Explains Pointer to Pointer or Double Pointer in C with Examples. Double pointer is a pointer that stores the address of another pointer.
Top answer
1 of 4
7

ptr_ptr is a pointer to a pointer to an int, and it points at ptr. ptr is a pointer to an int, and it points at n. n is an int, which has been set to 10.

A prefix '*' is the de-reference operator, meaning "the thing pointed to by". So **ptr_ptr evaluates to *ptr which evaluates to n, which is 10. If it helps, consider **ptr_ptr as equivalent to *(*ptr_ptr).

What's it for? Two possible uses are

  1. Passing a pointer as a parameter to a function, where you want the function to be able to change the pointer to a different one.
  2. Passing an array of pointers to a function, as in the classic int main(int argc, char **argv).

I have never encountered any need for an int ***ptr_ptr_ptr, but it's valid C.

2 of 4
3

A pointer-to-pointer simply means that you have an address of a memory location where some other pointer is stored. You dereference it twice to get to the final typed value.

int i = 123;
int* pi = &i;
int ** ppi = &pi;
int j = **ppi;

There are a surprising number of situations in which you need to use one of these beasties.

  1. As an output argument of a function call, pass a pointer to the pointer you want output or modified.
  2. Accessing an array of C null-terminated strings; each string is itself a pointer. The argc argument to main looks like that.
  3. 'Jagged' or N-dimensional arrays, stored as array of pointer to data. The data will usually be allocated with malloc().
  4. A 'handle' for a memory block, so the owner of the block can move it without the user of the block needing to know.
  5. Manipulating a structure that itself contains pointers, such as linked lists, trees and so on. It's basically impossible to insert an item into a linked list without them.

It's important to keep these conceptually separate. Although they all seem to use the same construct, in reality the underlying purpose is quite different. And I'm sure there are others I've missed.

I won't provide more code. There is an excellent example with diagrams and code here: http://www.eskimo.com/~scs/cclass/int/sx8.html.