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
Answer from pmg on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › c language › c-pointer-to-pointer-double-pointer
C - Pointer to Pointer (Double Pointer) - GeeksforGeeks
In C, double pointers are those pointers which stores the address of another pointer. The first pointer is used to store the address of the variable, and the second pointer is used to store the address of the first pointer.
Published   October 25, 2025
🌐
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.
Discussions

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
The double pointer explanation is needed.

In main() struct Node *list is a local pointer which is on the stack but it doesn't point to anything (yet). alloc_list(&list) passes the address of list so list can be given a value.

In alloc_list(), the malloc() grabs some heap memory and *listp is assigned a pointer to the malloc'ed memory. *listp is actually *list from main() so this is where the struct Node pointer is given a value. At the end of the for loop, listp is overwritten with the address of the first struct's next variable. This means that the second time round the for loop, the malloc'ed memory pointer will be stored in the first struct.

Each loop creates a new struct on the heap with a pointer in the previous struct and a pointer to the first struct is held by main(). Hopefully that answers your question.

More on reddit.com
🌐 r/C_Programming
7
0
July 30, 2019
Initialize a double pointer to a struct inside another struct?
ms1 is allocated on init's stack, so it ceases to exist after init returns as the other comment mentions, the arrow operator is for deferencing pointers, you only need the dot operator for ms1 More on reddit.com
🌐 r/C_Programming
2
7
December 8, 2020
🌐
TutorialsPoint
tutorialspoint.com › home › cprogramming › c pointer to pointer
C Pointer to Pointer
June 10, 2012 - C - Pointers vs. Multi-dimensional Arrays ... A pointer to pointer which is also known as a double pointer in C is used to store the address of another pointer.
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);
}
🌐
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.
🌐
W3Schools
w3schools.com › c › c_pointer_to_pointer.php
C Pointer to Pointer (Double Pointer)
C Examples C Real-Life Examples C Exercises C Quiz C Code Challenges C Compiler C Syllabus C Study Plan C Interview Q&A C Certificate ... You can also have a pointer that points to another pointer. This is called a pointer to pointer (or "double ...
🌐
Sololearn
sololearn.com › en › Discuss › 2987799 › what-is-advantage-of-using-double-pointer
What is advantage of using Double Pointer? | Sololearn: Learn to code for FREE!
February 22, 2022 - With double pointers You can reorganize tons of data in the memory by simply referring to the memory address A Pointer as the name implies points to a location in the memory. It holds the address of the variable it is pointing to.
Find elsewhere
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.

🌐
Quora
cstdspace.quora.com › What-practical-uses-do-double-pointers-have-in-C
What practical uses do double pointers have in C? - C Programmers - Quora
Answer (1 of 20): It’s real simple. C passes values by copying them into the function. The function call frame makes storage for the value locally and copies the value into the local copy. When the function returns, the copy is either eliminated or copied as a return value. Pointers, same way. ...
🌐
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.
🌐
Quora
quora.com › What-is-a-double-pointer-in-C
What is a double pointer in C? - Quora
Answer (1 of 6): double pointer: double pointer points or stores address of a pointer which stores address of another variable. double pointer are used when we want to store address of a pointer.
🌐
Quora
quora.com › How-do-I-access-a-value-using-a-double-pointer-in-C
How to access a value using a double pointer in C++ - Quora
Answer (1 of 7): Let’s start ... (a pointer to a pointer). Literally, “double pointer” means “pointer to double”, and that’s not what you’re talking about. Even if your instructor, colleagues, ......
🌐
zakuarbor
zakuarbor.github.io › blog › double-pointers
A look at Double Pointers
October 25, 2020 - A double pointer is a pointer to another pointer. We know a pointer is a data type that stores some address as its value. Therefore, a double pointer is a data type where it stores an address of another pointer which itself points to another ...
🌐
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.
🌐
Coconote
coconote.app › notes › e536c889-9296-4693-b416-d545c8bd6fb7
Understanding Double Pointers in C | Coconote
A pointer to a pointer in C is used to store the address of another pointer. The first pointer stores the address of a variable. The second pointer stores the address of the first pointer, hence called double pointers.
🌐
W3Schools
w3schools.com › c › c_pointers.php
C Pointers
In the example above, we used the pointer variable to get the memory address of a variable (used together with the & reference operator). You can also get the value of the variable the pointer points to, by using the * operator (the dereference operator):
🌐
TheJat
thejat.in › home › learn › c++ › compound types: references and pointers in c++ › double pointers
Double Pointers - TheJat.in
We initialize the double pointer pp by assigning the address of the pointer p to it using the syntax int** pp = &p;. Now, pp holds the memory address of p. ... To access the value of x using the double pointer pp, we use the dereference operator (*) twice: **pp. The first dereference (*pp) retrieves the address of the pointer p. The second dereference (**pp) retrieves the value stored at the address pointed to by p, which is the value of x. ... We print the value of x using the double pointer: std::cout << "Value of x using double pointer: " << **pp << std::endl;.
🌐
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' .
🌐
Codedamn
codedamn.com › news › c programming
What are double pointers in C?
March 10, 2024 - A double pointer is declared by using two asterisks (**) before the variable name. It effectively points to a pointer, allowing for a level of indirection that is crucial for certain programming tasks.