Someonewhohaveacat
Someonewhohaveacat

Reputation: 83

Printing value of a pointer to a pointer

I am trying to wrap my head around "pointer to a pointer". And I tried some experiments and I got stuck here for a while:

int array[5] = {4 , 5 ,6 ,7 ,8};
int *p = array;
int **pp = &p;
for ( int i = 0; i < 4; i ++)
{
    printf("\nprinting\n");
    printf("Source: %d\n", array[i]);
    printf("Output by pointer: %d, %d\n", p[i], *(p + i));
    printf("Output by pointer to a pointer: %d, %d\n", *pp[i], **(pp + i) );
}

And I got this as output:

printing
Source: 4
Output by pointer: 4, 4
Output by pointer to a pointer: 4, 4

printing
Source: 5
Output by pointer: 5, 5

I don't understand why after 1 loop, the program stop at the 2nd loop- line 9. Did I misunderstand anything basic knowledge or something else. Thank you for reading.

Upvotes: 0

Views: 375

Answers (4)

4386427
4386427

Reputation: 44256

This line is wrong

printf("Output by pointer to a pointer: %d, %d\n", *pp[i], **(pp + i) );

You need to change it to

printf("Output by pointer to a pointer: %d, %d\n", (*pp)[i], *(*pp + i) );

so that you dereference the double pointer before using it as a normal pointer.

You can think of it like this:

p is the same as (*pp)

In other words - in a valid expression that uses p you are allowed to substitute p with (*pp). That is

p[i]     --> (*p)[i]
*(p + i) --> *((*pp) + i) --> *(*pp + i)

Notice that the parenthesis is important. The parenthesis can be removed in the second example but not in the first as [] has higher precedence than *.

Doing pp + i generates a pointer that doesn't point to any valid object. So when you dereference it using **(pp + i) you do an illegal access an your program crashes.

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 310910

For starters it is unclear why there is used the magic number 4 in the loop instead of the number 5 that is the number of elements in the array

for ( int i = 0; i < 4; i ++)
                 ^^^^^

The pointer pp does not point to first element of an array. It points to a single object

int **pp = &p;

So these expressions

*pp[i]  (that is equivalent to *(pp[i] )

and

**(pp + i)

does not make sense.

An expression using the pointer p can be written using the pointer pp like *pp.

So these correct expressions

p[i]

and

*(p + i)

can be written using the pointer pp the following way (just substitute p for *pp taking into account operation precedences)

( *pp )[i]

and

*( *pp + i )

Upvotes: 2

Tom Karzes
Tom Karzes

Reputation: 24052

Change the last printf to:

printf("Output by pointer to a pointer: %d, %d\n", (*pp)[i], *(*pp + i) );

You're basically using *pp in place of p, but the * operator doesn't group as tightly as [] so you need to use parentheses in the first form. In the second form, you need to dereference pp before adding i, after which the result is dereferenced.

Upvotes: 2

OznOg
OznOg

Reputation: 4722

You acesses to pointer thru pointer-to-pointers are wrong: you must access the pointee as the array:

int array[5] = {4 , 5 ,6 ,7 ,8};
int *p = array;
int **pp = &p;
for ( int i = 0; i < 4; i ++)
{
    printf("\nprinting\n");
    printf("Source: %d\n", array[i]);
    printf("Output by pointer: %d, %d\n", p[i], *(p + i));
    printf("Output by pointer to a pointer: %d, %d\n", (*pp)[i], *(*pp + i) );
}

Upvotes: 0

Related Questions