Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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);

The short answer is that type matters; a pointer to int is a different, incompatible type from pointer to pointer to int. As others have mentioned, different pointer types may have different sizes and representations.

A pointer value is not just an address; it has additional type semantics. For example, the expression ptr++ will advance the pointer to the address of the next object of the base type. If the base type is char, then the pointer is advanced 1 byte. If the base type is int, the pointer is advanced sizeof (int) bytes.

Simply put because it will confuse the compiler. The compiler can work only according to the language standard. It doesn't have a brain of its own.

The language standard tells the compiler that if there is a int *

go to the address stored in that variable and use it.

In case there is a int ** then it tells it

go to the address in that variable. You aren't done yet as that is also an address. Go there and use what is present there.

This goes on and on for int *** and so on.

Hope this helps you to get over this basic confusion.

If you could assign any address to any pointer regardless of type, on the grounds that one address is just like any other address, consider the trouble you could get yourself into if the following became legal:

int n = 40;
int * p = &n;
int ** pp = &n;  /* Typeless address assignment as you would like */
printf("%d\n", **pp); /* Bad Things happen here */

or the other way round:

int n = 40;
int * p = &n;
int * p2 = &p; /* More typeless address assignment */
printf("%d\n", *p2); /* Definitely not what you want */

Even if one address was the same as any other, sensibly dereferencing a pointer would become somewhat troublesome if things worked the way you suggest.

The reason you can't do what you suggest is that the type information you'd lose under your proposal is needed for dereferencing to work. If all you wanted pointers to do was to store and retrieve addresses, you'd have a point, but they're not just used for this. If they were, we could just have void pointers and be done with it.

I completely agree to your statement that when pointer variable always would store a value that is integer, as the address to any variable/array would be an integer.

But still the data-type that is used to declare the pointer is the one of whose address it would be storing.

There are 3 points:

 1. The bits that are used while storing integer values differ from machine to machine.
    i.e. 32-bit, 64-bit and further more complications may add-up.

 2. Memory occupied i.e. bytes of data stored in it. Reason is : somewhere even the pointer variable is stored in memory. Right?

 3. There are certain operations associated with pointers like ++ or --.

Remember, pointer type is dependent on the type of variable it points to. This is the reason/need for the pointer to pointer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top