suppose I have the following code in C:
int x = 1025;
int *y = &x;
What is &y? Is it the address in memory of the pointer variable y?
What is the pointer variable y? Does it hold the address of the variable x?
What is &x? Is it the address in memory of the variable x itself or is it the address its value, 1025?
What is the variable x? Is it the address of its value, 1025?
What is *y? Is it the address of 1025 = variable x ?
and the big one...
If printing &y displays the address of y, printing &x displays the address of x, but printing x/*y just prints 1025, how would I print the address of 1025?
Sorry if some of these questions seem really obvious, but I've had a lot of confusion messing with pointers that I'm trying to clear up.
[EDIT] Guys, I found my mistake; I was thinking that the variable x would hold the address of the sequence of bytes representing 1025. Standard Java-to-C maladjustment. Thank you all for the responses
Given:
int x = 1025;
int *y = &x;
Q1. What is &y? Is it the address in memory of the pointer variable y?
Yes. It is the address of the variable y, and has the type int **.
Q2. What is the pointer variable y? Does it hold the address of the variable x?
Yes. It is a pointer variable that (after the code fragment) holds the address of x.
Q3. What is &x? Is it the address in memory of the variable x itself or is it the address its value, 1025?
It is the address of the variable x. It so happens that x holds 1025 at the moment, but when that value changes, &x still points to the variable x, and therefore to the current value of x and not to 1025 (because x contains a different value now).
Q4. What is the variable x? Is it the address of its value, 1025?
The variable x is a memory location that currently holds the value 1025, but this could change. Values such as 1025 do not themselves have addresses — that is a concept from OO languages (I think Smalltalk has that sort of concept; I think Java uses it for object types, but not the simple non-object types like int‡) and not a C concept.
Q5. What is *y? Is it the address of 1025 = variable x?
It is not the address of 1025; that's the easy part. If you use int i = *y;, then *y is the value in the variable that y points to, which is currently x, which currently has the value 1025, so i is set to 1025. If, however, you use *y = 1024;, then *y is the variable that y points to, which is x, so the value stored in x (and *y) changes from 1025 to 1024.
Q6. If printing &y displays the address of y, printing &x displays the address of x, but printing x/*y just prints 1025, how would I print the address of 1025?
The first two assertions are fine. The 'but' assertion needs to be written x / *y with a space between the / and the * as otherwise you have started a comment. However, that should not print 1025 but should print 1. If you are getting 1025, then you wrote something like:
printf("%d\n", x/*y); /* comment */);
There is no address for 1025 per se. There might be various addresses for various variables that currently hold the value 1025, but there is no single address for the value 1025. That is a non-C concept, as already mentioned.
‡ If someone disagrees with the Java or Smalltalk references, let me know by comment and I'll remove the one those that are wrong. They are not a key part of my argument — I'm just trying to explain that some languages do have a concept loosely analogous to 'address of 1025', even though C does not.
What is &y? Is it the address in memory of the pointer variable y?
Yep. You can have pointers-to-pointers as well.
int x = 357;
int *y = &x;
int **z = &y;
What is the pointer variable y? Does it hold the address of the variable x?
Yes. Basically, it is an integer-ish type that (as its value) holds the address of 'x'.
What is &x? Is it the address in memory of the variable x itself or is it the address its value, 1025?
The address to the variable, which, with an integer, is also where the value is stored.
What is the variable x? Is it the address of its value, 1025?
It is the location in memory of several bytes, that hold data. How the data is interpreted depends on the code that uses it. With integers, the data is meant to represent a number (like 1025) but it could just as easily be manipulated as if it was something else, like a couple chars or a float. Data in memory is merely data in memory - what gives it meaning is how it is used.
What is *y? Is it the address of 1025 = variable x ?
1025 is merely the data stored at the address of 'x', the value stored in those bytes of memory doesn't change the location of 'x' at all. Once 'x' is created, it's location in memory (for the duration of its lifetime) doesn't change.
So *y is x. *y 'dereferences' the address stored in 'y' (x's address), and so then you're operating on the block of memory that both 'x' and '*y' refer to.
If printing &y displays the address of y, printing &x displays the address of x, but printing x/*y just prints 1025, how would I print the address of 1025?
Printing x/*y should print 1. x = 1025. *y = 1025. 1025/1025 = 1
1025 doesn't have an address. 1025 is a bunch of bits in a few bytes somewhere. 1025 is the sequence of bits (that your code gives a meaning to, but that has no meaning on its own) stored in several bytes that is located at the address stored in 'x' and '*y'.
If we assume an integer is four bytes of memory (32 bit OS and hardware, let's say), then you have four bytes in some random location in RAM:
[01000100] [1101010] [00101001] [11010101] (gibbish binary for illustration)
The binary bits stored in those four bytes don't mean a thing, until your code decides how to interpret the meaning of those bits.
'x' is those four bytes. 1025 is converted to binary and stored in those four bytes. The address of 'x' is the address of those four bytes. 'y' is a chunk of bytes that you store the address of 'x' at. '*y' lets you operate on the bytes that 'y' stored the address of. Accessing *y gives the same bytes pointed to that x refers to.
What is &y? Is it the address in memory of the pointer variable y?
Yes.
What is the pointer variable y? Does it hold the address of the variable x?
Yes.
What is &x? Is it the address in memory of the variable x itself or is it the address its value,
1025?
It is the address of x. x can change, for example if you set it with 'x = 1024' in a later line, but its address would remain the same
What is the variable x? Is it the address of its value, 1025?
x is a variable, which means it takes up some space in memory, and the bits in that space have the integer value of 1025.
What is *y? Is it the address of 1025 = variable x ?
*y dereferences the pointer, which means it gets the value of the memory at that address. So it returns 1025.
Your 'big question' is just question #3.
What is &y? Is it the address in memory of the pointer variable y?
&y is the address at which the contents of variable y are stored, those contents being the address of (pointer to) an int.
What is the pointer variable y? Does it hold the address of the variable x?
Yes, y is a pointer that holds the address of variable x.
What is &x? Is it the address in memory of the variable x itself or is it the address its value, 1025?
&x is the address of x, so the address in memory of the variable itself, not of the constant value you initialized it with.
What is the variable x? Is it the address of its value, 1025?
The variable itself is just a region of storage in memory, an "object" in C terms. Internally, the compiler uses the name to find the address of that region of storage.
What is *y? Is it the address of 1025 = variable x ?
*y is the value of whatever y points to, in this case, 1025.
how would I print the address of 1025?
It is not legal to take the address of a literal constant in C (except string literals), for a variety of reasons, including that it might not have an address.
Yes, yes, the address (that's why & is called the "address of" operator), no, no.
Here's how you should think of variables in C. They are scraps of paper that you can write a value on. (The type of the value should match the type indicated on the piece of paper.) All the scraps of paper are bound together in a notebook so that you can address them by a page number, which we call the address.
Pointer variables are special pieces of paper on which you write the page number. You can later check the pointer, see which piece of paper it points to, and look at that instead.
It follows from this that:
A variable has an address. It's a piece of paper with a page number.
A value does not have an address. It's not a piece of paper, it's something like a number that you can write on a piece of paper. A number like 1025 does not have a page number, but when you write "1025" on a page you call x, then there is a page, with a page number, that has 1025 written on it.
To convince yourself that you can't take the address of a value, try something like &1025. The compiler won't allow that.
exactly. A pointer is a variable and as a variable has its own memory address.
Yes, the pointer y is initialized with the address of the variable x
&x is the address of the variable x. You can print it if you want to clearly see the difference.
The variable x is saved at a certain address in the memory. This is different from the value with which the variable is initialized, in this case 1025.
Again, to see the difference, try to print out the address of x and its value:
int x = 1025;
printf("%p", &x); //prints the address of x
printf("%d", x); //prints the value assigned to x
Last question: *y is the variable pointer and the dereference operator *, This means that you get the value saved in the variable that y points to.
Well actually if you print x/(*y) then you should get 1 as a result because you would have 1025/1025
Related
I'm trying to wrap my head around pointers but it's confusing at the moment.
When a C compiler comes across a variable in memory it naturally reads the value present. If "X" was equal to 8 then the value of X would be read out as 8.
But when a compiler comes across a pointer in memory, it doesn't read the value of the pointer (the value of the pointer is random) but it instead goes to the address stored in the pointer.
But the thing is, every variable has a value and an address. Why does C specifically go the address of a pointer variable?
I'm not sure how to word this in a way that makes sense.
What is the point of declaring a pointer variable, when we can access the address of any variable using the & operator and print the pointer?
I'm having trouble visualising a pointer variable.
The way I see it now in my head is, every variable has an address and a value. This is a fact. I'm not sure what a pointer variable does since, like a normal variable, it also has a value and an address.
Pointer variables are treated the same as any other variable when it comes to storage.
Given the following declarations
int i = 1;
int *p = &i;
you get something like this:
Item Address Value
–––– ––––––– –––––
i 0x8000 1 // address values for illustration
p 0x8004 0x8000 // purposes only
The integer variable i is stored at address 0x8000 and contains the value 1. The pointer variable p is stored at address 0x8004 and contains the address of i.
IOW, the only difference between i and p is the type of value they store and what operations are allowed on them.
As for why we use pointers, they are required in the following cases:
To track dynamically allocated memory;
To allow a function to modify the value of an input parameter
They’re also useful in building dynamic data structures.
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.
Is the only way of getting the address of an address in C (opposite to double dereference to have an intermediate variable?
e.g. I have:
int a;
int b;
int *ptr_a;
int *ptr_b;
int **ptr_ptr_a;
a = 1;
ptr_a = &a;
ptr_ptr_a = &(&a); <- compiler says no
ptr_ptr_a = &&a; <- still compiler says no
ptr__ptr_a = &ptr_a; <- ok but needs intermediate variable
but you can do the inverse, e.g.
b = **ptr_ptr_a; <- no intermediate variable required
e.g. I don't have to do:
ptr_b = *ptr_ptr_b;
b = *ptr_b;
why are the two operators not symmetrical in their functionality?
The address-of operator returns an rvalue, and you cannot take the address of an rvalue (see here for an explanation of the differences between rvalues and lvalues).
Therefore, you have to convert it into an lvalue by storing it in a variable, then you can take the address of that variable.
It is probably easier to explain with an example memory layout like this:
Var Adr value
---------------------
a 1000 1
ptr_a 1004 1000
ptr_ptr_a 1008 1004
1008 1004 1008->1004->1000
You can obviously dereference ptr_ptr_a twice *ptr_ptr_a == ptr_a, **ptr_ptr_a == 1
But the variable a has an address (1000) what should address of an address mean if it is not the address of a pointer? &ais a final station. Thus &&a wouldn't make any sense.
When you ask for an address using '&', you ask the address for something stored in memory.
Using '&' 2 times means you want to get the address of an address which is non-sense.
By the way, if you use intermediate variable as you're doing it, you will get the address of the intermediate variable. Which means if you use 2 intermediate variable to compare addresses they will be different.
eg.:
int a = 0;
int* p = &a;
int* q = &a;
// for now &p and &q are different
if (&p == &q)
printf("Anormal situation");
else
print("Ok");
address of address of something is not possible, because an address of address would be ambiguous
You can get the address of something which hold the address of something, and you could have multiple occurances of that (with different values)
There's no such thing as the address of an address. You have a box, with a number on it. That is the number of the box in the memory sequence. There's no place which stores these numbers. This would also be extremely recursive as you can see.
If you think for a moment, you'll notice that in order to get the address of something, it must be in memory.
If you have a variable
int a
it has an address. But this address is, if in doubt, nowhere in memory, so it doesn't need to have an address. IOW, you only can get the address of a variable.
In the other direction, things are easier. If you have the address of something, you can dereference it. And if this "something" is a pointer, you can dereference it again. So the double indirection mentionne above is automatically given.
Put simply, only things physically held in the computers memory can have an address. Just asking for the address of something doesn't mean that the address gets stored in memory.
When you have an intermediate pointer, you're now storing it in memory, and taking the address of where it's stored.
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))
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.)