I was playing around with pointers the other day and came up with the following code where I explicitly cast an int variable to int * and print out the address of the explicitly casted variable
#include <stdio.h>
int main (void)
{
int d;
int *p1, *p2;
printf("%p\n", p1 = &d);
printf("%p\n", p2 = (int *) d);
return 0;
}
Here's the output:
ffbff71c
ffbff878
My question is what is that second address and what is contained there?
Garbage - you're printing out the value of an uninitialized variable. It's just total coincidence that it looks like your other address; initialize d to get a meaningful answer.
In the second print, you are not printing an address, but a value converted to an address!
In the first assignment, you're taking the address of the variable, which is just some RAM address. In the second assignment, you're converting the variable's value to a pointer. Since the variable is not initialized, that's the garbage value located at that RAM address.
It is just a random address in memory since d is not initialized.
As others have pointed out, you are converting an indeterminate value to a pointer. Performing that conversion, or indeed doing anything with that value other than overwriting it, produces undefined behavior.
If d's value were set prior to the conversion, then it would matter that C explicitly permits integers to be converted to pointers. However, for this case and most others, the standard says:
the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
[C2011, 6.3.2.3/5]
So basically, don't do that unless you know enough to determine reliably for yourself what the result will be with your particular combination of code, C implementation, compile and link options, and platform.
Related
Instead of initializing a pointer like this,
int main (){
int *ptr;
int x = 5;
ptr = &x;
}
What happens in memory when you do something like this?
int main (){
int *ptr = 100;
}
Would *ptr be looking for a random address that contains the value 100 or is it storing the value of 100 in ptr?
This is a constraint violation, the compiler should give you a diagnostic message. (If the compiler doesn't say "error" then I would recommend changing compiler flags so that it does). If the compiler generates an executable anyway, then the behaviour of that executable is undefined.
In Standard C, this code does not assign 100 to the pointer, as claimed by several other comments/answers. Integers cannot be assigned to pointers (i.e. using the assignment operator or initialization syntax with integer on the right-hand side), except the special case of constant expression zero.
To attempt to point the pointer to address 100, the code would be int *ptr = (int *)100;.
First of all, as mentioned in other answers, the code int *ptr = 100; is not even valid C. Assigning an integer to a pointer is not a valid form of simple assignment (6.5.16.1) so the code is a so-called "constraint violation", meaning it is a C standard violation.
So your first concern needs to be why your compiler does not follow the standard. If you are using gcc, please note that it is unfortunately not configured to be a conforming compiler per default, you have to tell it to become one by passing -std=c11 -pedantic-errors.
Once that is sorted, you can fix the code to become valid C by converting the integer to a pointer type, through an explicit cast. int *ptr = (int*)100;
This means nothing else but store the address 100 inside a pointer variable. No attempts have been made to access that memory location.
If you would attempt to access that memory by for example *ptr = 0; then it is your job to ensure that 100 is an aligned address for the given system. If not, you invoke undefined behavior.
And that's as far as the C language is concerned. C doesn't know or care what is stored at address 100. It is outside the scope of the language. On some systems this could be a perfectly valid address, on other systems it could be nonsense.
int *ptr = (int*)100; // valid
int *ptr = 100; // invalid as int to int * cast is not automatic
Usage of absolute address is discouraged because in a relocatable program segment, you would never know where a pointer should have as a value of some address, rather it should point to a valid address to avoid surprises.
Compiler won't give you any error. But it's a constraint violation. Pointer variables store addresses of other variables and *ptr is used to alter value stored at that address.
The long and short of it is nothing. Assigning the value 100 to the pointer value p does something; it sets the address for the pointer value to 100, just like assigning the value of the call malloc to it would; but since the value is never used, it doesn't actually do anything. We can take a look at what the value produces:
/* file test.c */
#include <stdlib.h>
#include <stdio.h>
int main() {
int *ptr = (int *) 100;
printf("%p\n", ptr);
return 0;
}
Executing this results in this output:
0x64
Pointers are, in a sense, just an integer. They (sometimes) take up about the same size of an integer (depending on the platform), and can be easily casted to and from an integer. There is even a specific (optional) type defined in C11 for an integer that is the same size as a pointer: intptr_t (see What is the use of intptr_t?).
Going back to the point, attempting to perform any dereferencing of this pointer of any kind can cause Weird Behavior(tm) - the layout of the memory is platform and implementation dependent, and so attempting to grab something at the address 100 will likely cause a Segmentation Fault (if you're lucky):
/* file test.c */
#include <stdlib.h>
#include <stdio.h>
int main() {
int *ptr = (int *) 100;
printf("%i\n", *ptr);
return 0;
}
Executing results in this output:
fish: "./test" terminated by signal SIGSEGV (Address boundary error)
So don't do it unless you know exactly what you're doing, and why you're doing it.
with:
int *ptr = 100;
you have assigned the value 100 to the pointer. Doing anything with it but printing its value will be undefined behavior:
printf ("pointer value is %p\n", (void *)ptr);
I am new to C and have some questions about the pointer.
Question 1 What`s differences b/w the following two? Which way is better to initialize a pointer and why?
int *p=NULL;
int *p;
#include <stdio.h>
void main()
{
char *s = "hello";
printf("%p\t%p",s);
//printf("%p\t%p",&s) it will give me unpredictable result every time
//printf("%p\t%p",(void *)&s) it will be fine
//Question3: why?
}
Question 2: I try to google what is %p doing. According to my reading, it is supposed to print the pointer. It that mean it print the address of the pointer?
Question 1, these are definitions of pointer p. One initializes the pointer to NULL, another leaves it uninitialized (if it is local variable in a function, and not global variable, global variables get initialized to 0 by default). Initializing with NULL can be good, or it can be bad, because compiler can warn you about use of uninitialized variables and help you find bugs. On the other hand compiler can't detect every possible use of uninitialized variable, so initializing to NULL is pretty much guaranteed to produce segmentation fault if used, which you can then catch and debug with a debugger very easily. Personally I'd go with always initializing when variable defined, with the correct value if possible (if initialization is too complex for single statement, add a helper function to get the value).
Question 2, %p prints the address value passed to printf. So printf("%p", pointer); gets passed value of variable pointer and it prints that, while printf("%p", &pointer); (note the extra & there) gets passed address of the variable pointer, and it prints that. Exact numeric format of %p is implementation defined, it might be printed just as a plain number.
Question 3 is about undefined behavior, because format string has more items than what you actually pass to printf. Short answer is, behavior is undefined, there is no "why". Longer answer is, run the application with machine code debugger and trace the execution in disassembly view to see what actually happens, to see why. Note that results may be different on different runs, and behavior may be different under debugger and running normally, because memory may have different byte values in different runs for various reasons.
1) The first is an initialization (to NULL in this case) the second is only a declaration of p as a pointer to int, no initial value is assigned to p in this case. You should always prefer an initialization to prevent undefined behavior.
2) You should cast to void* when using %p to print out a pointer (beware that you are using it too many times in your format specifier). The memory address to which p points is printed.
1)
int *p = NULL
defines and initializes a pointer 'p' to NULL. This is the correct way to initialize pointers in order to get "Seg Fault" if you forget to assign a valid address to this pointer later.
int *p
Only defines a pointer "p" with an unknown address. If you forget to assign a valid value to this pointer before using it, then some compilers will notify you about this mistakes while some others will not and you may access a non-valid address and get a run time error or undefined behaviour of the program.
2) "%p" is printing the address where the pointer is points. Since the pointer holds an address, then "%p" prints this address.
printf("%p\t%p",s);
So the first "%p" will print the address where the pointer "s" points which is the address which stores the string "hello". However, note that you are using twice "%p" but you providing only one pointer to print its address !!
Most compilers will not scream about this cause it is effect-less; however try to avoid it.
Answer1 :
int *p=NULL;
p is a pointer to a int variable initialized with NULL. Here NULL means pointer p is not pointing to any valid memory location.
int *p;
p is a pointer to a int variable. p in uninitialized. Reading uninitialized variables is Undefined Behavior. (one possibility if try to use is that it will throw a segmentation fault)
Answer2:
It prints content of pointer. I mean base address of string "hello"
The main difference is that in *p = NULL, NULL is a pre-defined and standard 'place' where the pointer points.
Reading from Wikipedia,
The macro NULL is defined as an implementation-defined null pointer constant,
which in C99 can be portably expressed as the integer value 0
converted implicitly or explicitly to the type void*.
This means that the 'memory cell' called p contains the MACRO value of NULL.
If you just write int *p, you are naming the memory cell with the name p but this cell is empty.
The value contained in the pointer 'p' from the structure below is wrong printed and i can not find the way to print it right. What's the right code for it?
The code:
#include <stdio.h>
struct my_struct{ //structure definition
int a,*p;
};
int main(){
my_struct var;
var.a = 5; //variable definition
var.p = &(var.a); //pointer gets address from variable
printf("%d\n",var.p); // the number 2686744 is printed instead of the number '5'
return 0;
}
The %d format specifier to printf expects an int, but you're passing it an int *.
You need to dereference the pointer to obtain an int:
printf("%d\n",*(var.p));
You are printing the literal address of the pointer (i.e. not the value it points to, but the address in memory of where it points) when you write printf("%d\n", var.p). To access the value pointed to you need to dereference the pointer with printf("%d\n", *(var.p)).
As a side note: if you ever do want to access the address of a pointer for whatever reason in a printf family function, use the %p format specifier instead: http://www.cplusplus.com/reference/cstdio/printf/
You're not dereferencing the pointer
my_struct var;
var.a = 5;
var.p = &(var.a);
printf("%d\n",*(var.p)); //this will work
Use *var.p at print to dereference the pointer p and get it's value. Right now you are printing the memory location in decimal.
Your pointer var.p is simply containing an address. When i say containing, i mean it's value is an address.
In your case, this is the var.a's address.
When you try to print its value, you will print the var.a's address.
If you want to print what is CONTAINED at this address, or what is the VALUE at this address, you have to put a star before it.
In your case, you do not want to print var.p's value, as this an address, but you want to print the value contained at this address, using *(var.p).
Take care, there may be a difference in some languages between "var.p" and "(var.p)".
Imagine these operations in mathematics : (2x3)² and 2x3².
On the first operation, the ² will affect the whole multiplication, when, in the second operation, the ² will only affect the number 3.
In fact, you may want to try it by yourself to know how the language you are using work, *var.p may give you a way different result :)
However, using parenthesis in this case is a good practice, even if the language does give the same result.
PS : Just an extra information, if you ever need to print an address (which is not your case at the moment, you only want to print a decimal) using printf, replace %d by %p.
What is the difference between these two code samples? When I print the variable p, it prints the assigned value like below.
int *p;
p = 51;
printf("%d",p);
Output: 51
When I try to assign p=15, am I making memory address "15" in the ram as a pointee to the pointer p? When I try to add int c = 5 +p; it gives output as 71. Why am I getting 71?
I thought that the memory address "15" could store any information of the OS, programs, etc. But it exactly stores int for precise. Though I change the value p = 150; it gives int . How is that possible? What's happening under the hood?! I really don't understand.
Your code is illegal. Formally, it is not C. C language prohibits assigning integral values to pointer types without an explicit cast (with the exception of constant 0)
You can do
p = (int *) 51;
(with implementation-defined effects), but you cannot do
p = 51;
If your compiler allows the latter variant, it is a compiler-specific extension that has nothing to do with standard C language.
Typically, such assignment makes p to point to address 51 in memory.
On top of that, it is illegal to print pointer values with %d format specifier in printf. Either use %p or cast pointer value to proper integer type before using integer-specific format specifiers.
So you're telling that pointer that it points to 0x15. Then, you tell printf to print it as a decimal integer, so it treats it as such.
This reason this works is that on a 32 bit system, a pointer is 4 bytes, which matches the size of an int.
p points to a place in memory. *p is the contents of that space. But you never use the contents, only the pointer.
That pointer can be viewed as just a number, so printf("%d",p) works. When you assign a number to it, it interprets that as an offset into memory (in bytes). However, the pointer is supposed to contain ints, and when you add a number to a pointer, the pointer advances by that many spaces. So p+5 means "point to the int 5 spaces past the one you're pointing at now", which for 4-byte ints means 20 bytes later, hence the 71.
Otherwise, you've said you have a pointer to an int, but you're actually just doing all your stuff to the pointer, not the int it's pointing to.
If you actually put anything into the place you were pointing, you'd run into all kinds of trouble. You need to allocate some unused memory for it (e.g. with malloc), and then read and write values to that memory using *p.
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))