How can I declare a double pointer and assign its value directly from a normal variable?
int a = 5;
int* b = &a;
int** c = &b;
int** d = &&a;//This does not work
int** e = &(&a);//This does not work
How can I declare a double pointer and assign its value directly from a normal variable?
int a = 5;
int* b = &a;
int** c = &b;
int** d = &&a;//This does not work
int** e = &(&a);//This does not work
How can I declare a double pointer and assign its value directly from a normal variable
You cannot. "double pointer" is not a special construct in C. It is a short name for a pointer-to-pointer. A pointer always points to a variable, i.e., something with a memory location. &a
is an "rvalue", not a variable. It has no memory location and, therefore, you cannot point to it.
The &&a
does not work due to the reasons described in the other answer.
However, you can form a desired pointer in a single expression with a help ofcompound literal added in C99. You can view those literals as unnamed local variables. Compund literal are not temporaries but fully legitimate l-values. It is safe to take their address.
int** d = &(int*){&a};
tstanisl suggested using compound literals, and that is a good way to do it, but do be careful. Those have automatic scope, so they do not survive after you return from the function you use them in.
In the code below, a
is global and doesn't to out of scope, but the address we store in the compound literal does. There is no problem with using it inside foo
, but once we return from foo
, the pointer we return points to stack memory that might get overwritten. (If you do not see a problem, try calling some functions between the call to foo
and printing).
#include <stdio.h>
int a = 42;
int **foo(void)
{
int **d = &(int *){&a};
printf("no problem here: %d\n", **d);
return d;
}
int main(void)
{
int **p = foo();
printf("but a big problem here: %d\n", **p);
return 0;
}
Another issue is that the same compound literal in the code is the same memory, so if you use one in a loop for example, you do not get new memory with each iteration; the memory is reused.
In this code, we have an array of integers, we run through it and get the address of a compound literal pointer to each of them. Quite the mouthful.
All the pointers in p
will end up pointing to the same address, where the compound literal is.
#include <stdio.h>
int main(void)
{
int a[5] = {1, 2, 3, 4, 5};
int **p[5];
for (int i = 0; i < 5; i++)
{
p[i] = &(int *){&a[i]};
}
for (int i = 0; i < 5; i++)
{
printf("*p[%d] = %p\n", i, *p[i]);
printf("**p[%d] = %d\n", i, **p[i]);
}
return 0;
}
I agree that compound literals are a nice way of getting the address of an address (pointer to a pointer), but do be careful.