简体   繁体   中英

What is the difference between derefencing and assigning the address of a variable to pointer variable in C?

See the two codes below!

int main() {
    int a = 12;
    int *p;
    *p = a;
}

and the this code,

int main() {
    int a = 12;
    int *p;
    p = &a;
}

In the first piece of code dereferenced the pointer as this *p = a , and in the second piece of code, the address of variabe a is set to the pointer variable.

My question is what is the difference between both pieces of codes?

In your first piece of code:

int main() {
    int a = 12;
    int *p;
    *p = a;
}

you have a serious case of undefined behaviour because, what you are trying to do is assign the value of a to the int variable that p currently points to. However, p has not been assigned an 'address', so it will have an arbitrary - and invalid - value! Some compilers may initialise p to zero (or NULL ) but that is still an invalid address (on most systems).

Your second code snippet is 'sound' but, as it stands, doesn't actually achieve anything:

int main() {
    int a = 12;
    int *p;
    p = &a;
}

Here, you are assigning a value (ie an address ) to your pointer variable, p ; in this case, p now points to the a variable (that is, it's value is the address of a ).

So, if you appended code like this (to the end of your second snippet):

*p = 42;

and then printed out the value of a , you would see that its value has been changed from the initially-given 12 to 42 .

Feel free to ask for further clarification and/or explanation.

Declaring *p and a is reserving some space in memory, for a pointer in first case, for what a is in the 2nd case (an int ).

In these both cases, their values are not initialized if you don't put anything in it. That doesn't mean there is nothing in it, as that is not possible. It means their values are undetermined, kind of "random" ; the loader just put the code/data in memory when requested, and the space occupied by p , and the one occupied by a , are both whatever the memory had at the time of loading (could be also at time of compilation, but anyway, undetermined).

So you take a big risk in doing *p = a in the 1 st case, since you ask the processeur to take the bytes "inside" a and store them wherever p points at. Could be within the bounds of your data segments, in the stack, somewhere it won't cause an immediate problem/crash, but the chances are, it's very likely that won't be ok!

This is why this issue is said to cause "Undefined Behavior" (UB).

The first one is bad:

int main() {
    int a = 12;
    int *p;
    *p = a;
}

It means: put the value of variable a into location, pointed by pointer p . But what the p points? probably nothing (NULL) or any random address. In best case, it can make execution error like access violation or segmentation fault. In worst case, it can overwrite any existing value of totally unknown variable, resulting in problems, which are very hard to investigate.

The second one is OK.

int main() {
    int a = 12;
    int *p;
    p = &a;
}

It means: get the pointer to (existing) variable a and assign it to pointer p . So, this will work OK.

When you initialized a pointer you can use *p to access at the value of pointer of the pointed variable and not the address of the pointed variable but it's not possible to affect value like that (with *p=a). Because you try to affect a value without adress of variable.

The second code is right use p = &a

What is the difference between dereferencing and assigning the address of a variable to pointer variable in C?

The latter is the premise for the first. They are separate steps to achieve the benefit of pointer dereferencing.


For the the explanation for where the difference between those are, we have to look what these guys are separately:


  • What is dereferencing the pointer?

First we need to look what a reference is. A reference is fe an identifier for an object. We could say "Variable a stands for the value of 12 ." - thus, a is a reference to the value of 12 .

The identifier of an object is a reference for the value stored within.

The same goes for pointers. pointers are just like usual objects, they store a value inside, thus they refer to the stored values in them.

"Dereferencing" is when we "disable" this connection to the usual value within and use the identifier of p to access/refer to a different value than the value stored in p .

"Dereferencing a pointer" means simply, you use the pointer to access the value stored in another object, fe 12 in a instead through its own identifier of a .

To dereference the pointer the * dereference operator needs to precede the pointer variable, like *p .


  • What is assigning the address of a variable to a pointer?

We are achieving the things stated in "What is dereferencing a pointer?", by giving the pointer an address of another object as its value, in analogy like we assign a value to a usual variable.

But as opposed to usual object initializations/assignments, for this we need to use the & ampersand operator, preceding the variable, whose value the pointer shall point to and the * dereference operator, preceding the pointer, has to be omitted, like:

  p = &a;

Therafter, The pointer "points" to the address the desired value is stored at.


Steps to dereferencing a pointer properly:

First thing to do is to declare a pointer, like:

 int *p;

In this case, we declare a pointer variable of p which points to an object of type int .


Second step is to initialize the pointer with an address value of an object of type int :

 int a = 12;
 p = &a;       //Here we assign the address of `a` to p, not the value of 12.

Note: If you want the address value of an object, like a usual variable, you need to use the unary operator of & , preceding the object.


If you have done these steps, you are finally be able to access the value of the object the pointer points to, by using the * operator, preceding the pointer object:

     *p = a;

My question is what is the difference between both pieces of codes?

The difference is simply as that, that the first piece of code:

int main() {
    int a = 12;
    int *p;
    *p = a;
}

is invalid for addressing an object by dereferencing a pointer. You cannot assign a value to the pointer´s dereference, if there isn´t made one reference before to which the pointer do refer to.

Thus, your assumption of:

In the first piece of code I dereferenced the pointer as this *p = a...

is incorrect.

You do not be able to dereference the pointer at all in the proper way with *p = a in this case, because the pointer p doesn´t has any reference, to which you are be able to dereference the pointer correctly to.

In fact, you are assigning the value of a with the statement of *p = a somewhere into the Nirwana of your memory.

Normally, the compiler shall never pass this through without an error.

If he does and you later want to use the value, which you think you´d assigned properly by using the pointer, like printf("%d",*p) you should get a Segmentation fault (core dumped) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM