I know that int *p is a pointer but what does int **p mean exactly? What type of value is that? When I say now p= something, how is that working? I am seeing this in the creation of two-dimensional arrays with pointers.
Asked
Active
Viewed 525 times
-1
-
Welcome to Stack Overflow! Please take the [tour] (you get a badge!), have a look around, and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) I also recommend Jon Skeet's [Writing the Perfect Question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/) and [Question Checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – T.J. Crowder Dec 02 '21 at 08:32
-
2This should be covered by any decent C tutorial or course. As you say, `int *` is a pointer to `int`. `int **` is a pointer to a pointer to `int`. (`int ***` is a pointer to a pointer to a pointer to `int`, and so on.) – T.J. Crowder Dec 02 '21 at 08:34
-
@T.J Crowder as far as I know the process of a pointer is to store the adress of another variable so you can acces the variable with *p and change its value from the pointer. But I don't understand how **p works, could you explain me how would be an example or the process please? It is really confusing – rayo7 Dec 02 '21 at 08:37
-
2Can you clarify (i.e. show us some code) what you mean with "I am seeing this in the creation of two-dimensional arrays with pointers."? – Allan Wind Dec 02 '21 at 08:47
2 Answers
2
In short, int **p;
is a pointer to a pointer to an int
. So, for example:
int i, j; // Integers;
int *p = &i; // Pointer to i
*p = 1; // i is now 1
int *q = &j; // Pointer to j
int **s = &p; // Pointer to p
**s = 2; // i is now 2
s = &q; // s now points to q (pointing to j)
**s = 16; // j is now 16
s = &p; // s now points to p (pointing to i)
**s = 3; // i is now 3
p = &j; // p now points to j
**s = 17; // j is now 17
One use case for a pointer to pointer could be a function which needs to output a pointer to an int
and return a success/failure status:
#include <stdbool.h>
bool getIntHandle(unsigned handleId, int **handle)
{
static int handles[] = {12, 23, 34, 45};
bool success = (handleId < sizeof(handles)/sizeof(handles[0])); // Check that handleId is in range
if(success)
{
*handle = &handles[handleId];
}
return success;
}
int main(void)
{
int *handle;
bool success = getIntHandle(2, &handle); // Get a pointer to the integer at index 2
printf("*handle = %d\n", *handle);
return 0;
}

nielsen
- 5,641
- 10
- 27
-
1By the way, `int **p` could be used for 2D arays because you can interpret `*p` like a pointer to an `int` array, so `**p` points to array of arrays of `int`. – tony_merguez Dec 02 '21 at 08:44
-
That is not the same as this? Int *p int *s int i p=&i s=p *s=2 and now i=2. Why Can't i do that? – rayo7 Dec 02 '21 at 08:46
-
@rayo7 - First, it's really hard to read that code without any `;` (and please use backticks around code in comments). Second, what is `y` in that code? It appears out of nowhere in `p = &y;`. – T.J. Crowder Dec 02 '21 at 08:49
-
@rayo7 your example is confusing, : in `p = &y`, `y` isn't defined. – tony_merguez Dec 02 '21 at 08:49
-
@rayo7 If you mean `p=&i;` (and add `;`s), then your example should be fine. – nielsen Dec 02 '21 at 08:50
-
@rayo7 of course you can do that, but `p` and `s` are used for the same purpose, so they are duplicated. – tony_merguez Dec 02 '21 at 08:52
-
Yes I mean that, so if that is fine what is the pointe of using **s? Also I dont understand the line of **s=&p. I don't understand because p is an adress because it is a pointer, and the & is to access an adress so you are accessing the adress of an adress.. I don't understand – rayo7 Dec 02 '21 at 08:53
-
@rayo7 Pointer to pointers are not needed very often. I will try to add an example in the answer. – nielsen Dec 02 '21 at 08:55
-
@rayo7 `**s` is a pointer which points to a pointer. `p` stores an adress (pointed value), `&p` is where this adress is stored. But you're not allowed to write `int * s = &p;`. If you don't understand why because you think `&p` is anyway an adress so it can also be stored in a simple pointer, you're wrong. I am sorry for not having the adequate words to explain you why, but what you're writing have a concrete meaning for the compiler. The compiler will allow you writing `*p` but not writing `**p`, and that will be what you will trying to do if you write `int * s = &p. – tony_merguez Dec 02 '21 at 09:01
-
I have to see a clear example, when was p defined? Is it int *p? p is not an adress itself because it is a pointer or is something that can store an adress? This is why it is confusing me to acces the adress os a pointer because i think that a pointer is an adress by itself so what is the reason of accesing the adress of a pointer if a pointer is an adress already? Sl ylu are accesing the adress of an adress? – rayo7 Dec 02 '21 at 09:16
-
@rayo7 `s` and `p` both store an address. The difference is that `p` stores the address of an `int` while `s` stores the address of another address (which is then the address of an `int`). So even though they are both addresses, C also needs to keep track of which data type the addresses are pointing to know the resulting data type when a pointer is dereferenced. I.e., it must know that `*s` is an address while `*p` is an integer such that expressions can be interpreted correctly... – nielsen Dec 02 '21 at 09:23
-
... e.g. `(*s)++` means "increase the pointer that `s` points to such that it points to the next integer" while `(*p)++` means "increase the integer that `p` points to". – nielsen Dec 02 '21 at 09:24
1
p
is a pointer to a pointer to an int
. It's the type int **p
and the variable p
stores an address.
Here is an example of its use. p
is an array of two integer pointers. The first of the pointers p[0]
points to an array of 3 integers, and the 2nd to an array of 4 integers (combined this is known as ragged array):
#include <stdio.h>
#include <stdlib.h>
int main() {
int **p = malloc(2 * sizeof(int *));
printf("p = %p\n", p);
p[0] = malloc(3 * sizeof(int));
printf("p[0] = %p\n", p[0]);
p[0][0] = 0;
p[0][1] = 1;
p[0][2] = 2;
p[1] = malloc(4 * sizeof(int));
printf("p[1] = %p\n", p[1]);
p[1][0] = 3;
p[1][1] = 4;
p[1][2] = 5;
p[1][3] = 6;
free(p[0]);
free(p[1]);
free(p);
return 0;
}
The most common use, however, is with a regular 2d array that is passed to a function which degrades to a pointer to a pointer.

Allan Wind
- 23,068
- 5
- 28
- 38
-
But to store the adress in a pointer of other pointer it is not easier to maje int *p int *l and p=l? I am not understanding it :( – rayo7 Dec 02 '21 at 08:40
-
1Using a 2d array here really makes your answer confusing. Not (yet) my downvote. – Jabberwocky Dec 02 '21 at 08:42
-
@Jabberwocky fair point, op mentioned "two-dimensional arrays with pointers." which was the only reason I brought it up. Added a better example, I think, but open to further feedback. – Allan Wind Dec 02 '21 at 09:28
-