Bobby Wan-Kenobi
Bobby Wan-Kenobi

Reputation: 925

Multiple levels of indirection in C

In an effort to really grasp pointers in C, I was experimenting with multiple levels of indirection. I understand the basics:

#include <stdio.h>

void indirection(int * n)
{
    *n = 3;
}

int main ()
{
    int n;

    indirection(&n);
    printf("Your number is %d\n", n);

    return 0;
}

But I want to take it to the extreme and want to write the function:

void indirection(int ****n)
{
   ****n = 3;
}

to set the value of n, and print it in main, but I keep getting segmentation fault and other errors.

So how should I declare n in main, and how to use its value?

Upvotes: 0

Views: 1456

Answers (3)

Clifford
Clifford

Reputation: 93556

You have not shown how you are calling the modified indirection() but the seg-fault is almost certainly down to how you are calling the function.

If you are calling it as in the original main() you should get a warning:

warning: passing argument 1 of ‘indirection’ from incompatible pointer type [-Wincompatible-pointer-types] 

and it will most likely seg-fault as you have observed. The waring is telling you something about the semantics of your code.

I am not going to bend my brain around this frankly ill-advised effort. Lets take a simpler case:

void indirection(int** n)
{
   **n = 3;
}

If you can get that working you can extrapolate step-by-step to higher levels of indirection.

A call to this might look like:

    int n ;
    int* pn = &n ;

    indirection( &pn ) ;

    printf( "Your number is %d\n", n ) ;

To add a further level of indirection you'd instantiate a another level pointer:

    int n ;
    int* pn = &n ;
    int** ppn = &pn ;

The point is at each level you need something concrete to point to. You cannot for example just add &s, for example:

indirection(&&n);

because while &n - address-of n makes sense; &&n address-of-address-of n does not because &n is not a stored variable with an address to take. IT will not in fact compile.

That is the how - I'll leave the why to you.

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 223795

Pointers must point to something (an object), not just a value, so you cannot create them “on the fly” using multiple & operators. To get a pointer to a pointer, you must first define a pointer and then take its address. To get further pointers, you must repeat this:

#include <stdio.h>

void indirection(int ****n)
{
    ****n = 3;
}

int main(void)
{
    int     n;
    int    *np  = &n;
    int   **npp = &np;
    int ***nppp = &npp;

    indirection(&nppp);
    printf("Your number is %d.\n", n);

    return 0;
}

That said, there is a way to create objects on the fly, using compound literals. This works because a compound literal is not a normal operand that evaluates some operation but is a way of creating a temporary object:

int main(void)
{
    int n;
    indirection(& (int ***) { & (int **) { & (int *) { &n } } });
    printf("Your number is %d.\n", n);
}

Upvotes: 2

H.S.
H.S.

Reputation: 12679

The parameter type of indirection() function is int **** i.e. pointer to pointer to pointer to pointer to an int which is nothing but address of a int *** type variable. So,

int **** type variable can hold address of int *** type variable.

int *** type variable can hold address of int ** type variable.

int ** type variable can hold address of int * type variable.

int * type variable can hold address of int type variable.

You can do:

#include <stdio.h>

void indirection(int ****n) {
    ****n = 3;
}

int main (void) {
    int n = 0;
    int *p1 = &n;
    int **p2 = &p1;
    int ***p3 = &p2;

    indirection (&p3);

    printf ("Your number is %d\n", n);

    return 0;
}

Upvotes: 4

Related Questions