# Thread: Pointer to a Pointer clarification

1. ## Pointer to a Pointer clarification

Hi guys. I'm looking at a 'pointers to pointers' tutorial here.

Code:
```int **ipp;
int i = 5, j = 6; k = 7;
int *ip1 = &i, *ip2 = &j;

ipp = &ip1;```
Code:
`Is (ipp = &ip1) == (**ipp = &i ) ?`

2. Short answer to your direct question: No, but **ipp points to the value of i.

Theoretically it would be equal to
Code:
`ipp = &&i;`
But there's no such thing as "&&" operand (for taking the address of an address).

The variable ipp is a pointer that holds the address of another pointer. That second pointer holds the address of i.

If you think of memory as a set of safetyboxes in a bank-vault: Each one has a number. A pointer is essentially a safetybox that contains the number of a different safetybox. So if we give these a number:
i is safetybox 123, and in it is 5.
ip is safetybox number 333, in it is the number 123
ipp is safetybox 400, and it contains 333.

&i is the number of the safetybox containing i. Of course, if we change the value of i, we change the value 5 that is in box 123. The safetybox is still 123.

Does this make some sense to you.

--
Mats

3. This does indeed make sense, yes. Thank you very much.

So I can only declare a pointer to a pointer if such a pointer already exists - I cannot just let it equal some variable.

i.e i cant just do this:
Code:
```int i = 5, **pp;
pp = &i;```
has to be:
Code:
```int i=5, **pp;
int *p = &i;
pp = &p;```
Also, why isn't it 'int **pp = &p' ? I would've thought this following on from 'int *p = &i'

I honestly do understand the analogy of the safetyboxes, but the specifics are still tripping me up.

Please correct me if I'm wrong but you cannot do this:
Code:
```void function( int **pp );
main() {
int i;
function( &i );
}```
It should be this:
Code:
```void function( int **pp );
main() {
int i;
int *p = &i;
function( &p );
}```
Is this correct?

4. OK, I tried to write a little test program.
Code:
```#include <stdio.h>

void myim( int ** );

int main(void) {

int i, *p;
i = 5;
p = &i;
printf("i is %d, p is %d\n",i, *p);
myim( &p );
printf("i is %d, p is %d\n", i, *p);
return 0;
}

void myim( int **pp ) {
*pp += 1;
}```
Output:
i is 5, p is 5
i is 5, p is -1077564144

I was expecting:
i is 5, p is 5
i is 6, p is 6

What went wrong?

5. Code:
```void myim( int **pp ) {
*pp += 1;
}```
this does pointer arithmetics. it changes where the pointer pointed to by pp points to -> effectively changes where p in main points to and that is not i anymore. it's the int that follows i in memory.
Kurt

6. If you want to increment what p points to, the function should look like
Code:
```void myim(int *p) {
*p += 1; // or (*p)++; or ++*p;
}```

7. OK, then why are chars an exception to the rule:
Code:
```#include <stdio.h>

void get_string(char **s)
{
*s = "this is just annoying";
}
int main(void)
{
char *s;
get_string(&s);
printf("s is \"%s\"\n", s);
return 0;
}```
prints 's is "this is just annoying"'.

Now:
Code:
```#include <stdio.h>

void myim( int **pp ) {
*pp = 7;
}

int main(void) {

int *p;
myim( &p );
printf("p is %d\n", *p);
return 0;
}```
Compilation error. Now I know this is because p isn't pointing to anything, but with the same code for a char type, this rule doesn't seem to apply.

@robatino: i would have to pass '&i' in that case. The whole point to this is to use pointers to pointers.

@ZuK: I thought that was the case, thanks for clarifying. Out of curiosity, is there any way to change p and i? Do i have to change i first in order for p to change? In that case, what I was attempting was impossible?

8. OK, then why are chars an exception to the rule:
Code:
```#include <stdio.h>

void get_string(char **s)
{
*s = "this is just annoying";
}
int main(void)
{
char *s;
get_string(&s);
printf("s is \"&#37;s\"\n", s);
return 0;
}```
In fact, this is due to how string are represented. Look at this little example

Code:
```#include <stdio.h>

char *string = "this is just annoying";

void get_string(char **s)
{
*s = string;   //  *(char **) = (char *)
}
int main(void)
{
char *s;
get_string(&s);
printf("s is \"%s\"\n", s);
return 0;
}```

And for your other example, you shouldn't get an error, you should only get a warning (in the case warning aren't shown as errors heh).
Now I know this is because p isn't pointing to anything, but with the same code for a char type, this rule doesn't seem to apply.
In fact, this is because int * differs in level of indirection from int, not because p isn't pointing to anything. Because you could write something like this
Code:
```#include <stdio.h>

void myim( int **pp ) {
*pp = (int *) 7;
}

int main(void) {

int *p;
myim( &p );
printf("p is %d\n", *p);
return 0;
}```
and get garbage value at the output (if the program execute correctly, which might not happen, you would get the value of a int starting at adress 7) but you shouldn't get a compilation error.

9. It might clarify things a bit if you wrote
Code:
`  printf("*p is &#37;d\n", *p);`
since you're printing *p, not p. On the other hand, myim(&p) is changing the value of p, not *p.

10. I apologize about bringing up an older thread; but I would like to add to it, rather then create a new thread.

I understand the "theory" behind pointers to pointers. However, I am having a hard time with the application of this topic. Besides using a function to return the pointer value, where else might I use pointers to pointers?

Thanks,

KiaiViper

11. Code:
`int main (int argc, char ** argv) ?`
;-)

QuantumPete

12. Originally Posted by kiai_viper

I understand the "theory" behind pointers to pointers. However, I am having a hard time with the application of this topic. Besides using a function to return the pointer value, where else might I use pointers to pointers?

Thanks,

KiaiViper
That would definitely be the most common scenario. Walking through pointer arrays is another
Code:
```int *arr[20];
int **pp;
int i;
pp = arr;
for(i = 0; i < 20; i++) {
if (**pp = 7) {   // is the pointer at this place in array pointing to 7?
printf("Found a seven\n");
}
pp++;
}```
--
Mats

13. Dynamically allocated 2d arrays: i.e.
Code:
```#include <stdio.h>
#define WIDTH 20
#define HEIGHT 20

int main(int argc, char** argv) {
int** arr;
int i, k, z=0;
arr = malloc(HEIGHT*sizeof(int*));
for (i=0;i<HEIGHT;i++) {
arr[i] = malloc(WIDTH*sizeof(int));
for (k=0;k<WIDTH;k++) {
arr[i][k] = z++;
}
}
return 0;
}```

14. Thanks for the responses. That was the clarification that I needed.

--KiaiViper