What is the address of a pointer in C? - c

int main()
{
int *p;
printf("%p \n", &p);
printf("%p \n", p);
return 0;
}
By executing this code I am receiving the following output:
0x16b77f710
0x104683f4c
I expected to get the same memory address, because the &p id not referenced to any other variable.
Why i am getting two different memory address?
Thanks,

The pointer is a normal object having (in your case type of int *). It cant point to itself because the type of such pointer would have to be int **
*image stolen from internet.

A pointer is a variable like any other. It has an address, which is typically the address in memory where that variable sits.
Like any other variable, a pointer variable also has some data in it. For a pointer variable, that data is the address of some other variable, the variable at which the pointer points.
The address of a variable, and the contents of a variable, are two totally different things. They are almost never equal.
Try this program, in which I give your variable p something to point to:
int main()
{
int i = 5;
int *p = &i;
printf("p: %p, p's address: %p\n", p, &p);
printf("i: %d, i's address: %p\n", i, &i);
}
You should notice two things:
As in your first program, "p" and "p's address" will be different.
Whatever value you see for "p", it will be the same as "i's address".

The reason is that a pointer, when declared, does not point to itself by default. Simplified you can imagine it in such a way that a pointer occupies 2 memory cells. 1 memory cell has the virtual address where the pointer itself is located (&p in your case), the 2nd memory cell contains the virtual address where the pointer points to (p in your case).
Since memory cells retain their value when they are deallocated, the cell containing the destination address of your pointer still contains an obsolete value from another, already completed process.
You would have the same phenomenon if you declare a new integer variable and then print its value with printf, you will see that there will already be some number in the new variable that will appear completely random. This is also due to the fact that there is still an obsolete value in the corresponding memory cell.

Let assume there is random memory block for just understanding name it a. Now assume that p is pointing to that memory block.
&p returns the address of memory block where p is present.
p returns the address of memory block(&a) to the variable/memory block(a) which p is pointing.
So of course it will give different memory addresses.

I expected to get the same memory address, because the &p id not referenced to any other variable.
Pointer variables do not automatically point to themselves; if you don't explicitly initialize them, then their initial value will be indeterminate (or NULL, depending on how they are declared).
There's nothing magic about pointer variables - like any other scalar, they store some kind of value; it's just that in their case, that value is an address of another object.
If you really want p to store its own address, you'll have to do something like
p = (int *) &p;
The cast is necessary because the type of the expression &p is int **, and you can't assign a pointer value of one type to a variable of a different pointer type. But, pointers to different types are not guaranteed to have the same size, representation, or alignment. On modern commodity hardware like x86 you can probably count on int * and int ** having the same size and representation, just be aware that doesn't have to be the case everywhere.

Related

Double Pointer and Local Scope Confusion

I am taking a c programming course on Udemy and am quite confused when passing a double pointer into a function. In the example, the instructor passes the address of a pointer as an argument to a function. Then, he de-references that double pointer parameter in the function and sets it equal to the address of a local variable (a).
#include <stdio.h>
#include <malloc.h>
void foo(int **temp_ptr)
{
int a = 5;
*temp_ptr = &a;
}
int main()
{
int *ptr = NULL;
ptr = (int*) malloc(sizeof(int));
*ptr = 10;
foo(&ptr);
printf("%d\n", *ptr);
return 0;
}
So, what we are doing here is changing the value of ptr to hold the address of a. Then, when we de-reference ptr, it should display the value of 5 and not 10, since we changed the value of ptr to hold the address of a.
This is indeed correct: it displays 5 and not 10.
However, what doesn't make sense here is that the variable a is in the local scope of the foo function. When we declare a, the memory allocated is put onto the stack frame; thus, when leaving the local scope of the function that memory is deleted and the frame is popped off of the stack. How can we still access that variable a with the ptr variable in the main function? Shouldn't that memory be completely wiped out?
Then, when we de-reference ptr, it should display the value of 5
Should is incorrect. printf("%d\n", *ptr); is undefined behavior (UB) as the address stored in ptr is invalid with the return of foo(&ptr);.
Output may print 5, may print 42, may crash. It is UB.
... correct that the memory of the stack should be completely wiped out
No. There is not specified wiping of memory. The result is UB.
But sometimes undefined behavior works?
"undefined behavior" is undefined. Even if it "works" today, it may not "work" tomorrow.
When we declare a, the memory allocated is put onto the stack frame; thus, when leaving the local scope of the function that memory is deleted and the frame is popped off of the stack.
This assumes an underling code model that is not specified by C. Other real possibilities exist.
How can we still access that variable a with the ptr variable in the main function?
As is, no defined way. Alternatively keep the address of a valid by making a static.
In Foo function, we are updating the address of our pointer. int a declared in foo function will be stored at some memory location. Now, we are assigning that location to our ptr(which is okay, ptr can point to any memory location of type int). But the issue is the value at that location is not in our control and this location can be used for any other purpose which may update the value at that location.
It means that our pointer is now pointing to location that may be updated by any other source.

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 (i.e. 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 1st 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).
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
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.
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 f.e. 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, f.e. 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).

How &a is a pointer to a if it generates the address of a?

I'm new to programming, and at present I am learning about pointers in C.
I know that pointers are the variables which contain or hold address of another variable. Today when I was more learning about it with K&R I got confused in a line which says "&a is a pointer to a" in a given function swap(&a,&b) in Page No. 80. How &a is a pointer? It is not a variable, it is the address of the variable. Am I right?
I know that arguments can be passed to a function in two ways: call by value and call by reference. The caller's value of the argument is not changed in the first one, but it can be changed in the second one.
My question is I had read that if we want to change the value of the variable we have to pass the pointer to it (i.e. the location of the value we want to modify). What is meant by that? I mean, do we have to pass pointers to the function? And what is the meaning of the statement, "we have to pass the pointers to the location we want to modify".
A pointer is not a variable. A pointer is a value.
A variable, in C, designates a storage location, and a value can be stored in that location. Thus, if you have a variable a declared with int a, then a is a variable in which an integer value can be stored. If you have a variable int *x, then x is a variable in which a pointer to an integer value can be stored.
The address of a storage location can be obtained using the & operator. E.g., &a is the address of the storage location designated by a, or the address of a, and can be stored in (among other things) a variable of the corresponding type. Thus you can have:
int a = 42; /* a is a variable of type int, and has value 42 */
int* x = &a; /* x is a variable of type int*, and has value &a */
Although analogies in programming are often dangerous, you might think of things like page numbers in a book. The page number of a page is not the same thing as the page, but page numbers can still be written down on pages. E.g., the table of contents page has lots of page numbers written down on it. Thus:
actual_page p = ...; /* a page structure */
page_number n = &p; /* a page number */
A pointer is an address. A pointer variable is a variable holding an address.
It is perhaps analogous to the difference between a literal integer 1 and an integer variable int a. One might refer to both a and 1 as integers, just as you might refer to &a and int* p as pointers.
Note also that &a is not an lvalue and cannot be assigned - so it is as you say not a variable, but it is a pointer nonetheless, and can itself be assigned to a pointer variable.
If a is a variable of some type T, then &a is an expression which evaluates to the address of that variable, also known as a pointer to that variable—the terms are interchangeable. &a has the type T*, which is pronounced “pointer to T”.
int x = 4; // 4 has type int, so we can assign it to an int variable.
int *p = &x; // &x has type int*, so we can assign it to an int* variable.
The reason that you can modify function arguments passed by pointer is that a pointer introduces a sort of alias for a variable. You can alter it from multiple locations, either directly (via the variable) or indirectly (via the pointer).
// modifying x modifies *p.
++x;
printf("%d %d\n", x, *p);
// modifying *p modifies x.
++*p;
printf("%d %d\n", x, *p);
As others have observed, a pointer is a particular kind of value, not a particular kind of variable.
With regard to calling functions:
You cannot "pass a variable to a function" in C. If you put a variable name in the argument list of a function call then the value stored in that variable is passed, not the variable itself.
Although in a general sense programming languages may provide for passing function arguments either by value or by reference, C provides only pass by value. You can emulate pass by reference in C, however, by passing a pointer (value) to the location where another value is stored. That's what swap(&a, &b) does: you are passing the locations where the values of variables a and b are stored (that is, pointers to those values).
Pointer contains the address - so synonymous.
When you pass by reference, you are passing in the address - to directly modify the value.
A pointer is a type of variable that stores the address to an object.
Basically, the pointer is the address.
Think of it as a piece of paper. When it has a number printed on it, it's an integer (or other numeric type).
A pointer is a piece of paper that says "the data is on the peice of paper in location x", where "location x" is the address of the object.
How &a is a pointer to a if it generates the address of a?
The terms pointer and address in C are synonymous.
When you create a variable:
int a = 0;
It is created in memory at a specific memory location, or address, with sufficient memory to hold 1 int.
&a does not generate the address, it simply provides the address.
The & operator can be used to set the address of a pointer to a specific location, such as this:
int a = 0;//a now exists in memory at a specific location;
int *b = {0}; // b is created in memory as a pointer, and can be assigned a location
b = &a; //b is assigned the location (address) of the variable a
Stated a little differently, in the previous line, & is referred to as the address-of operator, so:
b = &x; Can be Read: Assign to b (a pointer) the address of a.

C pointers Question

For :
int *a;
a is an address where an integer can be stored.
&a is an address where a is stored.
Then, where is &a stored?
And, where is &(&a) stored?
And, where is &(&(&a)) stored?
Where does this storing of addresses stop?
If you don't explicitly write &a it will not be stored anywhere. If you do write then the address will be computed and stored either in an unnamed variable (temporary) or a named varible you write.
For example:
functionCall( &a ); // address will be in a temporary variable used for passing the parameter
int** b = &a; // address will be stored in variable b
otherFunctionCall( &&a ); // illegal, since &a is an expression operator & can't be applied to it
&a is a constant.
&(&a) is illegal.
a is not "an address where an integer can be stored". a is a variable large enough to hold the address of an integer. The only "integer" you can store directly in a is the address of an integer, viewed as an integer itself:
int *a;
int b;
a = &b;
printf("a is now %x\n", (unsigned int) a);
It is correct that a itself has an address, which is &a, but that address is not stored somewhere explicit, at runtime.
At a stretch, you might be able to store something that looks like the integer 0:
a = 0;
But this is just a shorthand syntax for "the NULL pointer", i.e. a pointer value guaranteed to not be the address of any actual object.
&a is the address of a. It is a value, result of operator & applied to a, and is not "stored", and has no address, so &(&a) is invalid. It's like 2+3.
int *a is a variable the size of a pointer, just like int b would an automatic int variable.
If this declaration is in a function, that variable is automatic and stored on the [stack](http://en.wikipedia.org/wiki/Stack_(data_structure)#Hardware_stacks) at runtime (a simple stack decrement allocates memory for it).
If the declaration is global, then 'a' is simply mapped in executable's .DATA area.
Any more & signs appended can 'create storage', because of the temporary variables you're using to hold'em ;) :
b = &a; //the address in the executable's .DATA or on the stack (if `a` auto)
c = &b; //the address of `b` on the stack, independent of `a` or `&a`
d = &c; //the address of `c` on the stack, independent of `a` or `&a`
z = &(&a); //error: invalid lvalue in unary '&'
The last line complains about the fact that & requires the operand to be a lvalue. That is, something assignable - like b and c above. (&a) as is a result of an expression which is not stored anywhere, therefore is not a lvalue.
You can keep going forever:
int value = 742;
int *a = &value;
void *b = &a;
void *c = &b;
void *d = &c;
You wouldn't put it on a single line without assigning it to anything - in that case it would be invalid.
At the crux of your problem seems to be a lack of understanding of the physical nature of memory and pointers. Not how the code works. As Im sure you know, physical memory is comprised of a large group of adjacent cells. The addresses of these cells are fixed and hard-coded by the computer itself, not by software apps or the programming language that you use. When you refer to &a, you are referring to the physical block of memory that is currently holding your value you've stored within the computers ram. "a" is simply a name that you've given the computer so that it knows exactly what block of memory to find the value that you've stored. I think that pretty much covers memory address.
Lets go over pointers now. A pointer is yet another memory address, that is referred to by the computer. It has whatever name that you give it. In this case it should be called something else besides the same name that you gave your first value. Lets call it "b". Based on how you declared it. b's memory location is only capable of holding one type of data....another memory location.... so when I say: b= &a I'm saying that the memory address of 'b'(which is designed only to hold memory addresses), is to hold the memory address of 'a'. Meanwhile on the other side of town, the memory address of 'a' has an integer stored in it.
I hope that this didnt get confusing, I tried not to get all techno-babble on you here. If youre still confused. Post again, Ill explain with code next time.
-UBcse
In C, a variable x may act as a value (on the right hand side of =, where it is called an rvalue), or it may act as a container for values (on the left hand side of =, where it is called an lvalue). You may take the address of x, because you can take the address of any lvalue—this gives you a pointer to the container. But because a pointer is an rvalue, not a container, you can never take &(&x). In fact for any lvalue l, &l is legal but &(&l) is never legal.
a is a variable of type "address of int";
&a is the address of variable a;
&(&a) would be the address of the address of variable a, which makes no sense
Not quite. a is a variable in which an address of some integer may be stored. &a is the address of a, i. e. the address of the variable a, which may contain an address of some integer.
Very Important: until and unless an address of something is assigned to a, it is an uninitialized pointer. Trying to use whatever it points to will lead to unpredictable results, and will likely crash your program.
You can have a pointer to a pointer.
Ex:
void foo(int **blah)
{
int *a = *blah;
...
}
A pointer does take up memory. It's just a small container that holds the address of something. It just can't take up "no space" because everything in the computer is represented somehow by numbers. It's just that as far as C/C++ is concenred, int *a is simply a pointer to an object and takes up no space. That is to keep you from having to manage any sort of memory... it keeps the machine seperated from the code.
int *a; is a pointer to an int called 'a'.
&a; is the derefrence of int *a. it's pointing to itself. this is what you would use to point to the variable that you wanted to pass around from function to function. derefrence is just a fancy word for "getting the address back"
&(&(&a)) is not a valid expression as previously stated. you may make a pointer to a pointer to a pointer. That may be what your thinking of. In such a case you would derefrence the last pointer in question and the computer should understand what you're talking about.
To answer the "where is 'a' stored" question; on the stack.
please, if i'm incorrect on anything, let me know.
&a is a number which is an rvalue: you can store it somewhere if you want to in a variable you will have declared or allocated, of type int*.
To wit:
int a = 42;
&a; /* this does not store the address of a because you've not assigned the value to a variable */
int **aptr = &a; /* aptr is on the stack */
int **aptr2 = (int*)malloc(sizeof(int*));
aptr2 = &a; /* aptr2 is in the heap */
&(&a) is not legal syntax.
If you want a pointer to a pointer to an int:
int b = 39;
int *bptr = &b;
int **ptr2bptr = &bptr;
You have to build up the levels of indirection.
With the above you can then do this if you want:
printf("%d\n", *aptr);
printf("%d\n", *aptr2);
printf("%d\n", *bptr);
printf("%d\n", **ptr_to_bptr);
Producing output of:
42
42
39
39
int* a;
This line simply declares a pointer to an integer. That pointer has a memory location, which you can get the address of using &a. & is an operator that returns the address of whatever it is run on. But if you do not assign this value anywhere, there is no further &-ing possible.
As to your question as to where &a is stored, most likely in a register. If you do not use the value, it will be immediately discarded. (And registers do not have memory addresses, which is why you cannot do &(&a))

Does a pointer also have any address or memory allocation?

If a pointer stores the address of a variable ... then from where do we get the pointer?
What I asked was that if we are using pointer directly, then there must be a location from where we get this pointer?
Yes, a declared pointer has its own location in memory.
In the example above, you have a variable, 'b', which stores the value "17".
int b = 17; /* the value of 'b' is stored at memory location 1462 */
When you create a pointer to that variable, the pointer is stored in its own memory location.
int *a;
a = &b; /* the pointer 'a' is stored at memory location 874 */
It is the compiler's job to know where to "get the pointer." When your source code refers to the pointer 'a', the compiler translates it into -> "whatever address value is stored in memory location 874".
Note: This diagram isn't technically correct since, in 32-bit systems, both pointers and int's use four bytes each.
Yes. Below I have an int and a pointer to an int and code to print out each one's memory address.
int a;
printf("address of a: %x", &a);
int* pA = &a;
printf("address of pA: %x", &pA);
Pointers, on 32bit systems, take up 4 bytes.
In C:
char *p = "Here I am";
p then stores the address where 'H' is stored. p is a variable. You can take a pointer to it:
char **pp = &p;
pp now stores the address of p. If you wanted to get the address of pp that would be &pp etc etc.
Look at this SO post for a better understanding of pointers.
What are the barriers to understanding pointers and what can be done to overcome them?
As far as your question goes, if I understand what you want, then, basically, when you declare a pointer, you specify an address or a numeric index that is assigned to each unit of memory in the system (typically a byte or a word). The system then provides an operation to retrieve the value stored in the memory at that address.
The compiler deals with translating the variables in our code into memory locations used in machine instructions.
The location of a pointer variable depends on where it is declared in the code, but programmers usually don't have to deal with that directly.
A variable declared inside a function lives on the stack or in a register, (unless it is declared static).
A variable declared at the top level lives in a section of memory at the top of the program.
A variable declared as part of a dynamically allocated struct or array lives on the heap.
The & operator returns the memory location of the variable, but unlike the * operator, it can't be repeated.
For example, ***i gets the value at the address **i, which is the value at address *i, which is the value stored in i, which the compiler figures out how to find.
But &&i won't compile. &i is a number, which is the memory location the compiler uses for the variable i. This number is not stored anywhere, so &&i makes no sense.
(Note that if &i is used in the source code, then the compiler can't store i in a register.)

Resources