Reputation: 925
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
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
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
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