Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should I use double pointer variable to receive another pointer's address(&ptr1)

int num = 45,*ptr1,*ptr2;
ptr1=#
ptr2=&ptr1;
printf("%d\n",*ptr1);

I've been thinking about this question for a while, but couldn't find a way to understand it,why &ptr1 can not be assigned to ptr2 in line 3, &ptr1 is a pointer's address,this address is no different from other address like an address of an integer, say

int a=1;
ptr2=&a;

Which means that I can assign an integer's address to a pointer,but not a pointer's address to a pointer,what differences between these two "address" could possibly make them different? Address of common variables can be assigned to single pointer,but address of pointers can not be assigned to single pointer?

I know the right way to do it is use double pointer to declare ptr2,but why single pointer can't?

like image 791
user2556058 Avatar asked Jul 16 '13 14:07

user2556058


3 Answers

Simply put, pointers are not addresses, they are varibles representing an address with a type. So the types have be compatible for pointers to assign (with the exception of void * generic pointer).

ptr2 = &ptr1;

ptr1 has a type of int *, so &ptr1 has a type of int **, it's not the same with ptr2, which has a type of int *.

Reference: C99 6.5.16.1 Simple assignment

both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right.

like image 200
Yu Hao Avatar answered Oct 19 '22 06:10

Yu Hao


Yes you can assign a pointer's address to a pointer, but it must be a pointer to a pointer variable.

int **ptr3;
ptr3 = &ptr1;

The reason you can't assign it the way you were trying is that a pointer to an int is not the same as an int. Pointers must be pointing to the same type to be compatible. If you really know what you're doing you can explicitly cast it, but that's a path to danger.

like image 1
Mark Ransom Avatar answered Oct 19 '22 07:10

Mark Ransom


Your code is wrong. This expression:

ptr2 = &ptr1;

Attempts to make an int * out of an int ** without a cast. The C standard forbids such conversions without an explicit cast.

The reason it's not allowed is that pointer types aren't guaranteed by the standard to all be the same size - so the pointer to your pointer might not fit in the variable you declared to be a pointer to an int.

Since pointers to any type can be converted to and from void * implicitly, you could write (correct, but probably confusing) analogous code to that in your question:

int num = 45;
void *ptr1, *ptr2;
ptr1 = #
ptr2 = &ptr1;

But doing so will require you to carry around all of the type information in some other way:

printf("%d\n",*(int *)ptr1);
printf("%d\n",*(int **)ptr2);
like image 1
Carl Norum Avatar answered Oct 19 '22 07:10

Carl Norum