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.
Related
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.
In the following code I would like to understand better what is happening with int *z = malloc(sizeof(int);
To me that creates a pointer to an int. Then *z gets the sum of the value that x points to (2) and the value that y points to (4).
Now *z = 6. Does that mean *z does not point to anything? It just stores an int? I thought *z was a pointer and a pointer is an address? Thank you for any help understanding.
int *add(int *x, int *y)
{
int *z = malloc(sizeof(int));
*z = (*x) + (*y);
return z;
}
int main(void)
{
int a = 2;
int b = 4;
int *ptr = add(&a, &b);
printf("sum = %i\n", *ptr);
}
Now *z = 6. Does that mean *z does not point to anything? It just stores an int? I thought *z was a pointer and a pointer is an address? Thank you for any help understanding.
You are correct with *z = 6 however you are wrong with how this happens.
z is a pointer and so it point somewhere into the memory. Earlier in your program, with int *z = malloc(sizeof(int)); you have allocated a space the z points to.
Then when you did *z = (*x) + (*y); you've basically put the result of the addition into that allocated space.
z still points to that space (because it is a pointer). *z is called dereferencing and has a meaning of reaching directly for the value the pointer points to.
In other words: the 6 is stored in a place the z points to and *z is a way to grab that value.
*z = 6 assigns 6 to the location pointed at by ptr. That's what a pointer does, it points to things, but in order to put a value at where it's pointing as opposed to changing the pointer you need to de-reference with the * operator.1
Imagine your memory as, conceptually, a number of bytes each of which has a number. A pointer to an int represents a particular location in memory which is presumed to hold an int, or 4 bytes worth of data.
*z = 6 means "put an integer value of 6 in the memory location described by z", which translates into machine instructions that are largely the same.
z absolutely does not "store an int", it stores a location. That location may exist, or may be NULL, or may be invalid. There's no guarantees unless you've checked your code carefully to ensure the pointer is valid. That's your responsibility as a programmer.
That's also why pointers can be tricky and frustrating. They introduce indirection in your code.
1 In C pointers are also largely interchangeable with arrays so you can do z[0] = 6, though as z only points to a single int, any index other than 0 is invalid.
int *z = malloc(sizeof(int));
this will envoke a system call for allocating one integer on the heap. z is the address of this integer return from malloc (if malloc fails to allocate z will be null)
z is a pointer to buffer allocated on the heap (if malloc success). in your case this buffer hold one integer so its a pointer to this integer.
see malloc description in man pages. malloc_man_pages
*z = (*x) + (*y);
you are right. you are assigning the value that sets in the address x and the value that sets in the address y to the place that z points to.
you dont check the return vale from malloc and this is a very bad thing. always check if malloc successd! see below. maybe you need to check the pointers that you get in x and y ?! (thats up to you, but i recommend to check).
int* add(int *x, int *y)
{
int *z = NULL;
if(x && y)
{
z = malloc(sizeof(int));
if(z)
{
*z = (*x) + (*y);
}
}
return z;
}
So just experimenting with pointers in C.
void inc(int *p){
++(*p);
}
int main(){
int x = 0;
int *p;
*p = x;
inc(p);
printf("x = %i",x);
}
Why is this printing "x = 0" instead of "x = 1"?
Here's your error:
*p = x;
You're dereferencing p, which is unassigned, and giving it the current value of x. So x isn't changed because you didn't pass a pointer to x to your function, and dereferencing an uninitialized pointer invokes undefined behavior.
You instead want to assign the address of x to p:
p = &x;
Alternately, you can remove p entirely and just pass the address of x to inc:
inc(&x);
Because you don't set p to the address of x
Use
p = &x;
instead of
*p = x;
With *p = x you cause undefined behaviour because p has indeterminate value and points *somewhere*. But you don't know where it points and with *p = x you write the value of x to that memory location.
You need to assign the address of x to p. As mentioned in the other answers you might just want to pass in inc(&x);. No need to declare a variable and waste it like that.
I am very new to C and currently having some trouble with pointers and I am not sure if my logic is correct on this question clarification would be great.
Is the second expression legal? Why or Why not? What does it mean?
int** x = ....;
... **x ...
This is all the question gives and I came up with the following answer (I think its in the ballpark)
The int** x will initialize a pointer x to whatever address/value that is after the equal sign.
**x ... will dereference the pointer to a value/variable
The question link that was proposed in the edit was just showing the difference between int* p and int *p which is nothing what i asked i understand this already.
int *x is a pointer to int. int** y defines y as a pointer to pointer to int, so it points to a pointer, and the latter points to an int. Example:
int n = 42;
int* x = &n; // points to n
int** y = &x; // points to x, which points to n
In this case y is a pointer to pointer. First indirection *y gives you a pointer (in this case x), then the second indirection dereferences the pointer x, so **y equals 42.
Using typedefs makes everything looks simpler, and makes you realize that pointers are themselves variables as any other variables, the only exception being that they store addresses instead of numbers(values):
typedef int* pINT;
int n = 42;
pINT x = &n;
pINT* y = &x; // y is a pointer to a type pINT, i.e. pointer to pointer to int
If you use double * you are telling the compiler you want a pointer pointing to another pointer:
int x = 4;
int *pointer = &x;
int **pointer_pointer = &pointer;
printf("%d\n",**pointer_pointer); // This should print the 4
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