What is the difference between *a=b and a=&b? - c

Given:
int **a; // (double pointer)
int *b; // (pointer)
Is there any difference between *a=b and a=&b?

The first, *a = b; copies the value of the variable b to the location a points to.
The second, a = &b copies the address of b to a.

*a = b;
You're assigning the value of b to wherever a is pointing to.
a = &b;
Here you're assigning the address of b to a

& it's the operator that gets the address of a variable
* is the operator that is able to retrieve the value pointed by a pointer, the indirection as you should call this process.
so yes, this 2 statements are different.

*a = b Assigning b to the location in memory where a is pointing at
a = &b Assigning the address of b to the variable a.

I think the question here is what is the difference between the two in practice. This example illustrates this:
int x = 10;
int *y;
int *z;
y = &x;
*z = x;
printf("x: %d, *y: %d, *z: %d\n", x, *y, *z);
x = 20;
printf("x: %d, *y: %d, *z: %d\n", x, *y, *z);
The value pointed to by z does not get updated to the new x value of 20, while the value pointed to by y does.

*a=b : *a is a pointer variable which stores the address of another variable i.e. b and
a=&b : a is just a normal variable which stores address of b even though it stores address of b it would not store complete address which depends on data type

Related

C Pointer address of difference

int main() {
int *x;
int *y;
y = x;
printf("%p %p", &x,&y); // prints 0061FF1C 0061FF18
printf("%p %p", x, y); // prints 00400080 00400080
return 0;
}
Why don't these print the same thing? I thought using just the x and the &x would get to the same value. Also, why are the bottom ones matching if the top one's arent?
When you say y = x in this case it just means that y assumes whatever pointer value x happened to have. You never initialized x with a value, so it's just some random junk.
The address of x and y themselves is going to be different. These are two separate variables representing two separate pointers. You can assign their value to be the same, but their address remains distinct.
You're probably confusing this behaviour with:
int x = 5;
int* y = &x;
Where now y == &x but &x and &y continue to remain distinct.
As C does not have references, you really don't have situations where two independent variables are ever the same address.
Suppose you wrote this:
int main() {
int x = 5;
int y;
y = x;
printf("%p %p", &x, &y);
printf("%d %d", x, y);
}
Would you expect both lines to print the same?
With int *x; you set x as a pointer. Its value is the address of the pointed value.
So:
*x = the integer value
x = the pointer, i.e., the address of the value, address stored at x
&x = the address of the pointer. This is the address of the address.
Then y=x; copies the uninitialized address, not the value.

Can I change the address of the pointer variable in C language?

For example, if there is a pointer variable int *a, int *b and each address value is 1000, 2000, can the address value of the pointer variable be swapped as if it were swapping the value of the common variable?
Note, I mean the address of the pointer. Not the value it contains.
As far as I know, the address value of the pointer variable is fixed and cannot be changed, is that right?
From comments:
A lot of people answered, but I think I asked the wrong question. I'm sorry, but my question is not about "change content of a pointer variable", but "change address of a pointer variable."
No, that's impossible for any variable. Not just pointers.
Can I change the address of the pointer variable in c language?
While the answer to your question would be yes for many other languages, including C++, kind of:
"While C++ doesn't directly support putting a variable at a given address, the same effect can be achieved by creating a reference to
that address:"...
...the answer for C is No. "A pointer has an address like other variables (which can't and needn't be changed)". (quote from 4th response in link.)
For C, the address of all variables (with the exception of those declared as register) are assigned at the time of declaration as a memory location provided by the operating system, and are immutable for the remainder of their life, no matter the scope in which they were created.
So, while the address pointed to by a pointer variable can be changed, the address of the variable itself, cannot.
Yes, you can:
void swapPointers(void **a, void **b) {
void *t = *a;
*a = *b;
*b = t;
}
void someOtherFunc() {
int *x = malloc(sizeof(int));
int *y = malloc(sizeof(int));
*x = 3;
*y = 5;
printf("x = %d y = %d\n", *x, *y);
swapPointers(&x, &y);
printf("x = %d y = %d\n", *x, *y);
}
Yes, you can swap the address the pointer points to.
int main()
{
int x = 5, y = 10;
int* p1 = &x;
int* p2 = &y;
printf("Address pointed by p1 is: %p\n", p1);
printf("Address pointed by p2 is: %p\n", p2);
//Here goes the swapping
int* p3 = p1;
p1 = p2;
p2 = p3;
printf("\n--After swap--\n");
printf("Address pointed by p1 is: %p\n", p1);
printf("Address pointed by p2 is: %p\n", p2);
}
I think you mean swapping addresses stored in pointers because you can not swap addresses of pointers as declared variables themselves.
To swap two objects in a function you have to pass them by reference. Otherwise the function will deal with copies of the values of passed directly to it objects.
In C passing by reference means passing an object indirectly through a pointer to it.
Pointers are the same objects.
So you can write the swap function the following way
void swap_ptr( int **a, int **b )
{
int *tmp = *a;
*a = *b;
*b = tmp;
}
And the function can be called like
int *a = /*...*/;
int *b = /*...*/;
//...
swap_ptr( &a, &b );
yes you can you just need to swap where each pointer point to.
declare a 3rd pointer then do the swap as follow.
//we have *a and *b
int *tmp;
tmp = a;
a = b;
b = tmp;
yes you can swap the address stored in two pointer using a temporary pointer variable. But if the pointer is declared as constant pointer for exapmle const int *ptr1; then it not possible because the address stored in ptr1 cannot be modified
#include <iostream>
using namespace std;
int main() {
int a=10;
int b=20;
int *ptr1;
int *ptr2;
ptr1=&a;
ptr2=&b;
cout<<ptr1<<" "<<ptr2<<"\n";
int *temp;
temp=ptr1;
ptr1=ptr2;
ptr2=temp;
cout<<ptr1<<" "<<ptr2;
return 0;
}
you can change the syntax to c because I thought that I was answering a question from c++ section

Is it possible without using any array to assign value of an integer to a designated address?

I'm recently reading about pointers in C but stuck at a point. I need to provide an example to make the question more clear.
I have declared two integer variables as a and b and assigned values 55 and 88 to them. Now by using the & symbol I can access their address and declare pointers as follows:
#include <stdio.h>
int main(void)
{
int a = 55;
int b = 88;
int *pa = &a;
int *pb = &b;
printf("Address of 'a' is: %p\n", &a);
printf("Address of 'b' is: %p\n", &b);
printf("Desired new address for the value of 'b' is: %p\n", (pa+1));
//What to do here to assign the value of b into the address (pa+1) ?
}
What I try to achieve(without using any arrays) is that: I want the value of b to be assigned to the address next to a.
I can obtain the address of a by &a or *pa = &a and the next address would be (pa+1). Now the pointer pa holds the address to the variable a. And so the value of (pa+1) I guess should point the address of the next possible address of a.
Now my problem is having the value of b and the address (pa+1) how can we register/assign the value of b to the address (pa+1)?
edit:
Following doesn't work:
int a = 55;
int b = 88;
int *pa = &a;
int *pb = &b;
printf("Address of 'a' is: %p\n", &a);
printf("Address of 'b' is: %p\n", &b);
printf("Desired new address for the value of 'b' is: %p\n", (pa+1));
*(pa + 1) = b;
printf("New address of 'b' is now: %p\n", &b);
Outputs:
Solved:
int main(void)
{
int a = 55;
int b = 88;
int c;
int *pa = &a;
int *pb = &b;
printf("Address of 'a' is: %p\n", &a);
printf("Address of 'b' is: %p\n", &b);
printf("Desired new address for the value of 'b' is: %p\n", (pa+1));
*(pa + 1) = b;
printf("New value at pa+1 is now: %d\n", *(pa+1));
}
To write a value to an address, you use *address = value;.
For example,
*(pa + 1) = b;
However, by doing this, you are very likely to overwrite some piece of memory that was supposed to be used for something else, and crash your program.
Your edit to the question makes it apparent that you want to change the address of a variable. This is impossible. If it was possible, it would be written like &b = pa + 1;.
To write the value of b to the address you want you need to use:
*(pa + 1) = b
But bare in mind that this causes undefined behaviour so you may get what you want or you may not, no way of knowing for sure.
This way you will write the value but the address of b won't change, that's why in your print you don't see any difference.
You have (pa+1) which is an address of type int *, so all you need to do is dereference it:
*(pa+1) = b;
You can then subsequently print that value like this:
printf("valud=%d\n", *(pa+1));
Note however that what you're doing, writing past the memory bounds of an object, is not allowed by the C standard and in fact invokes undefined behavior. Such code is only useful when attempting to execute an attack such as a buffer overflow.

Pointers and Memory Allocation in C

Program:
int x;
int *y;
int **z;
z = (int **) malloc (sizeof(int *));
y = (int *) malloc (sizeof(int));
x = 1;
*z = &x;
*y = x;
.
.
.
Question:
What is the difference between:
*z = &x;
*y = x;
From what I understand *z points to the address of x and *y points to x, but for *y to point to x doesn't that require the address of x? I don't really understand what's going on with these two variables.
Edit:
I also want to know when do we know when a variable is allocated on the stack or on the heap?
Why is x,y, and z allocated on the stack?
Why is *y, **y, *z, **z, allocated on the heap?
Finally, does changing *z, change **z?
z is a pointer to a pointer (which will typically point to a dynamically allocated array of pointers).
y is a pointer to int. Again, more often than not it'll point to a dynamically allocated array of ints.
So, the *z = &x; is setting the pointer that z refers to to point at x. I.e., z points at a pointer, which (in turn) points to x.
*y = x; is taking the value of x and assigning it to the int pointed to by y.
For things like this, a picture is often helpful. So, our basic definitions give us this:
The we do:
z = (int **) malloc (sizeof(int *));
y = (int *) malloc (sizeof(int));
Which gives us this:
Then we do:
*z = &x;
*y = x;
Which gives us this:
In all of these, a dashed line signifies a pointer from one place to another, while the solid line indicates copying a value from one place to another.
We can then consider the long-term differences between them. For example, consider what happens if we add x=2; after all the assignments above.
In this case, *y will still equal 1, because we copied the value 1 from x to *y. **z will equal 2 though, because it's just a pointer to x -- any change in x will be reflected in **z.
This line stores the address of variable x in the memory pointed to by z:
*z = &x;
This line stores the value of x into memory pointed to by y:
*y = x;
The two assignment statements are unrelated: the second one makes a copy, while the first one does not. If you change the value of x and then retrieve **z, you will see the new value of x; however, retrieving *y would give you back the old value of x (i.e. 1).

Pointer value of *x &x and x

suppose this code:
main()
{
int *x;
*x = 3;
printf("%d %d %d\n", *x, &x, x);
// output 3 5448392 2293524
}
if *x is the value; &x the addres; what does mean that value of x?
*x is the value (correct)
x is the address of the value. EDIT In your case, this address is uninitialized, so it is not pointing anywhere in particular (thanks Keith Nicholas for mentioning this).
&x is the address of the [pointer that should contain the] address of the value.
(it's worth pointing out that your program may crash :)
Adr value expression
----------------------------------------------
5448392 2293524 &x address of x
2293524 3 x place where you assigned 3
x gives you the address in memory where value of *x, i.e. 3 is located. &x gives the address where value of x, i.e. 2293524 is located.
It is the address that x contains. Having been declared as a pointer, x stores an address, while &x is in a sense a pointer to a pointer.
EDIT: So I wasn't as precise as perhaps I should have been. &x is strictly speaking not a pointer to a pointer. It is the address of a pointer. In the following line of code, y is a pointer to a pointer:
int **y = &x;
x is a pointer to an int, its not an int itself, its not the address of an int, its a pointer.
a pointer contains an address of an int.
so, a missing step you have ( your program doesn't point x to anything! very dangerous)
int y = 5;
int *x;
x = &y // put the memory location of y into the pointer
if you now print the contents of the pointer...
printf("%d\n", x); // prints out the memory location of y;
now to get to the value of what your pointer points to ( at the moment, y)
printf("%p\n", *x); // prints out 5;
now, just like y has a memory location, x also has a location in memory
so &x is where the pointer 'x' is in memory
x is uninitialized so it points to nowhere and dereferencing it with * is undefined behaviour.
The following would be a more correct (and useful) program
main()
{
int x; //declare an int variable
int *xp; //declare a pointer to an int variable
xp = &x;
*xp = 3;
printf("%d %d %d %d %d\n", x, &x, xp, *xp, &xp);
}
x is a value, xp and &xp point to that value, *xp can be used to access and change the value and &xp is a pointer to that pointer...
&x is the address of the pointer object.
The value of the pointer is the address of an int.
Also, you shouldn't assign to *x as in your example: x doesn't point anywhere valid.
x and &x values are of pointer types so you should use p conversion specifier to print their values.
printf("%d %p %p\n", *x, (void *) &x, (void *) x);
Don't forget to cast to void * otherwise the call to printfis undefined behavior. (p conversion specifier requires an argument of type void *).
int *x;
int y = 0;
x = &y;
*x = 3;
x is a pointer to int. *x is an int and its value is 3. And &x is a pointer to a pointer to int. Note that your pointer has to point to a valid object object (like above) otherwise it has an invalid value.

Resources