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

7

6
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?

Conaway answered 16/7, 2013 at 14:57 Comment(4)
You can assign integer address to integer pointer. If you want to assign pointer address, you need pointer to pointer type. It's about type safety. You can do what you want with brutal casting.Pothook
You could also argue that an int should be good enough to store the address...Telemark
@Maxime except where it isn't - i.e. you could be on a 64-bit platform where all pointers must be 64-bit, yet integers are still 32-bit. Arguably not common, but it is a permitted configuration...Verdin
Well, I like to think about it in the following terms: If you want two pointers pointing to the memory address of num (which holds a int) use ptr1=# ptr2=ptr1 if you want ptr1 pointing to the memory address of k, and ptr2 pointing to the memory address of ptr1 (which holds a pointer to an int) then you need a pointer of pointer. So, despite how much memory it takes to store ints and *ints, they are different mammals, with different contents.Stopover
E
3

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.

Earphone answered 16/7, 2013 at 15:2 Comment(6)
Grammatically speaking,"ptr1 has a type of int *, so &ptr1 has a type of int **" seems to be reasonable,but from what I can see,at line ptr2 = &ptr1; ptr1 is just an variable(forget it is a pointer),and & operator feteches its address and then assign it to ptr2,there's no difference while I assignning an integer's address to ptr2,what differences under this two addressConaway
@Conaway Right - the line ptr2 = &ptr1, given int *ptr1, *ptr2; should not compile, at least not without a big ugly warning... Sadly, some more permissive compilers aren't as diligent as they should be...Verdin
@Conaway Remember that every variable in C has a type, including pointer variables. So &ptr1 is more than just an address, the compiler knows what type of variable this address holds. You'll need a cast to let the compiler think it's some other type.Earphone
@YuHao we can also say that &ptr1 is a pointer,it is more than an address,but why pointer can not be assigned to another pointer,still don't understandConaway
@Conaway A pointer to int and a pointer to a pointer to int are two very different type. See the C99 standard I quote, for pointer assignment, there are some constraints to follow. Why not? Because C standard doesn't allow it.Earphone
@YuHao I understand it ,pointer to pointer is different type from pointer to int,so it needs two different declarationConaway
B
1

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.

Billye answered 16/7, 2013 at 15:0 Comment(7)
OP knows that, it's the last sentence in his question.Mulhouse
@CarlNorum, I just noticed that. So I edited the answer to add a bit more, hope that helps.Billye
I kind of understand it,pointer to int is one type,pointer to char is another type,so is pointer to pointer,it is another different type,when we need to store pointer to pointer type,the variable must be declared with "two asterisk" notation as we would "char asterisk" notation,because the pointer is pointing to different data type,am I right?Conaway
@user2556058, you almost have it - it's not just "pointer to pointer" it's "pointer to pointer to int", a "pointer to pointer to char" would be a different data type as well.Billye
What is the return value of & operator,purely address or a pointer object that contains much more info like the length and something else?Conaway
@Conaway the & operator creates a pointer. The value of the pointer is an address, but the type of the pointer is already known to the compiler and can be used to calculate the length for example. It isn't stored anywhere though.Billye
@Conaway The & operator has no "return value" in this context if you only see it as a normal function. In this context, where it's actually type algebra that's being used, & denotes an operation that maps an object (pointer to int) to another object (pointer to pointer to int) that the compiler then can use to calculate how to read or write to it. As a programmer, you see an address, but the compiler sees the typed object.Gordongordy
M
1

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);
Mulhouse answered 16/7, 2013 at 15:0 Comment(4)
why does &(int*) has the type int ** ?Boomer
Every time you take an address of a variable it's a pointer to the type of that variable. If you extend that to taking the address of a pointer, you get a pointer to a pointer.Mulhouse
why does &(int*) has the type int ** ?Boomer
Didn't I just answer that?Mulhouse
M
1

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.

Marchellemarcher answered 16/7, 2013 at 15:55 Comment(1)
You grasp the point,the main point is that they are of different types,and pointer is not equal to addressConaway
T
1

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.

Tolan answered 16/7, 2013 at 18:3 Comment(0)
C
0

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.

Cretic answered 16/7, 2013 at 16:2 Comment(0)
I
0

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.

Illeetvilaine answered 16/7, 2013 at 17:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.