In the below example pointer p is a pointer to a variable a.
I have incremented the value of p by 1, which increases the value by 4 because it is int.
But when I try to print the value of *p, some different value is displayed.
I have also attached the output with the program.
Can somebody explain why that value of *p is displayed?
// POINTERS
#include<stdio.h>
int main(){
int a = 3;
int *p = &a;
printf("Value of p %d \n",p);
printf("Value of *p %d \n",*p);
p = p+1;
printf("After changing : value of p %d \n",p);
printf("After changing : value of *p %d \n",*p);
return 0;
}
Output:
Link
[1]: https://i.stack.imgur.com/sTYlq.jpg
Can somebody explain why that value of *p is displayed?
No, no one can explain why the last print of *p gives the value you see.
And tomorrow it may print another value... or not print at all... or your program may crash... or something different may happen...
It's called undefined behavior.
You are trying to read a memory location (i.e. the original p + 1) as if there is an int located at that location. But there isn't... the C standard doesn't define what has to happen when you do that. So anything may happen.
Further notice that you actually have undefined behavior already here:
printf("Value of p %d \n",p);
^^
Wrong for pointers and therefore undefined behavior
To print a pointer you must use %p and cast the pointer to a void pointer. Like:
printf("Value of p %p \n", (void*)p);
^^ ^^^^^^^
Specifier cast to void-pointer
for void-pointer
So a legal version of your program:
int a = 3;
int *p = &a;
printf("Value of p %p \n", (void*)p);
printf("Value of *p %d \n",*p);
p = p+1;
printf("After changing : value of p %p \n", (void*)p);
// printf("After changing : value of *p %d \n",*p); <-- Illegal so commented out
You are accessing memory you do not (necessarily) have access to.
Imagine a (4-bytes long) is here
+-+-+-+-+-+-+-+-+-+-+-+-+
| | | |a|a|a|a| | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+
^ ^ ^ ^ ^ ^ ^ ^ <== memory you do not have access to
\------ | <== p points here
\------ <== p+1 points here and the pointer is valid
Accessing memory you do not have access to is Undefined Behaviour.
Related
I'm recently reading about pointers in C but stuck at a point. I need to provide an example to make the question more clear.
I have declared two integer variables as a and b and assigned values 55 and 88 to them. Now by using the & symbol I can access their address and declare pointers as follows:
#include <stdio.h>
int main(void)
{
int a = 55;
int b = 88;
int *pa = &a;
int *pb = &b;
printf("Address of 'a' is: %p\n", &a);
printf("Address of 'b' is: %p\n", &b);
printf("Desired new address for the value of 'b' is: %p\n", (pa+1));
//What to do here to assign the value of b into the address (pa+1) ?
}
What I try to achieve(without using any arrays) is that: I want the value of b to be assigned to the address next to a.
I can obtain the address of a by &a or *pa = &a and the next address would be (pa+1). Now the pointer pa holds the address to the variable a. And so the value of (pa+1) I guess should point the address of the next possible address of a.
Now my problem is having the value of b and the address (pa+1) how can we register/assign the value of b to the address (pa+1)?
edit:
Following doesn't work:
int a = 55;
int b = 88;
int *pa = &a;
int *pb = &b;
printf("Address of 'a' is: %p\n", &a);
printf("Address of 'b' is: %p\n", &b);
printf("Desired new address for the value of 'b' is: %p\n", (pa+1));
*(pa + 1) = b;
printf("New address of 'b' is now: %p\n", &b);
Outputs:
Solved:
int main(void)
{
int a = 55;
int b = 88;
int c;
int *pa = &a;
int *pb = &b;
printf("Address of 'a' is: %p\n", &a);
printf("Address of 'b' is: %p\n", &b);
printf("Desired new address for the value of 'b' is: %p\n", (pa+1));
*(pa + 1) = b;
printf("New value at pa+1 is now: %d\n", *(pa+1));
}
To write a value to an address, you use *address = value;.
For example,
*(pa + 1) = b;
However, by doing this, you are very likely to overwrite some piece of memory that was supposed to be used for something else, and crash your program.
Your edit to the question makes it apparent that you want to change the address of a variable. This is impossible. If it was possible, it would be written like &b = pa + 1;.
To write the value of b to the address you want you need to use:
*(pa + 1) = b
But bare in mind that this causes undefined behaviour so you may get what you want or you may not, no way of knowing for sure.
This way you will write the value but the address of b won't change, that's why in your print you don't see any difference.
You have (pa+1) which is an address of type int *, so all you need to do is dereference it:
*(pa+1) = b;
You can then subsequently print that value like this:
printf("valud=%d\n", *(pa+1));
Note however that what you're doing, writing past the memory bounds of an object, is not allowed by the C standard and in fact invokes undefined behavior. Such code is only useful when attempting to execute an attack such as a buffer overflow.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
#include<stdio.h>
int main()
{ int i;
int *p;
p = &i;
i=5;
printf("i = %d, p = %P, *p = %d\n",i,p,*p);
*p=6;
printf("i = %d, p = %P, *p = %d\n",i,p,*p);
return 0;
}
the output of this code is:
i = 5, p = %P, *p = -1009882308
i = 6, p = %P, *p = -1009882308
where it should give *p=5 in 1st statement and in 2nd statement *p=6
In your printf you try to display p = %P or %P doesn't exist, so the %P will be ignored and will be print like a string.
After, when you try to print *p = %d, you don't print the variable *p but you print p because p havn't been used by the %P.
Correct printf should be:
printf("i = %d, *p = %d\n",i,*p);
You have specified the following string as your formatted string to printf():
i = %d, p = %P, *p = %d
Then you specify three elements to be printed:
i, p, *p
So, %d gets replaced with the value stored in i, as expected:
i = 5, p = %P, *p = %d
All good so far, except for one thing: the format %P does not exist. Therefore, it gets skipped as a specifier and is instead printed out.
Then the second %d is replaced with the value in p, not *p, since the second %d is the next valid specifier, and p is the next variable to be used:
i = 5, p = %P, *p = -1009882308
Since there are no more specifiers left to use, *p gets ignored and a warning, or possibly an error, is thrown when compiling.
Congratulations, you just printed the address that p points to as an int, aka Undefined Behaviour.
So, how do we remedy this?
Replace %P with the actual valid specifier: %p. Now all variables and specifiers are used, and your code will run smoothly.
This is what printf() should've printed:
i = 5, p = C3CE6B3C, *p = 5
Note: using %p prints the address of p, which will be printed as a hexadecimal number.
EDIT: As chux stated, %p requires a corresponding void* to work as intended. Cast p to a (void*) in the printf() statement like so: (void*)p
Your format specifier has a typo, it is not recognized. As a result, you're passing the pointer to be printed as an integer. It should be like this:
printf("i = %d, p = %p, *p = %d\n",i,p,*p);
Most compliers will issue a warning for your code. If yours doesn't, please check if you can change the settings to be more strict with warnings.
Why the output of the following C code is like this?
yes my compiler gave warning for %P but if we don't focus on that then also for *p it should return value of i i.e., 5 and then 6 comment.
The key problem is assuming that code after a warning should behave well.
That warning was a result of using an invalid print specifier "%P". That leads to undefined behavior (UB). The rest of code no longer has any specified behavior. Thus "should return value of i i.e., 5 and then 6" is not support by C. The output could be anything.
Use valid print specifiers and matching arguments.
Use "%p" to print a void*. To convert p to a void*, apply a cast.
// printf("i = %d, p = %P, *p = %d\n",i,p,*p);
printf("i = %d, p = %p, *p = %d\n", i, (void*)p, *p);
%P is not a valid conversion specifier, so your second argument p is being printed as a decimal integer with %d, and *p is not being printed at all.
Change both lines to
printf("i = %d, p = %p, *p = %d\n",i, (void *)p,*p);
^
|
+---- note lower case p here
and you will get the output you expect.
CASE 1:
#include <stdio.h>
int main()
{
int arr[3] = {2,3,4};
char *p;
p = (char*) arr;
printf(" %p - %d\n",&p, *p);
p = p+1;
printf("%p - %d\n",&p, *p);
return 0;
}
output:
0x7ffde540b000 - 2
0x7ffde540b000 - 0
In above code value of pointer 'p' is increased by 1 - but address doesn't changed.
Again I increased the value of p by 4 (i.e p = p+4).
This time I get the following output -
0x7ffe50a2dff0 - 2
0x7ffe50a2dff0 - 3
pointer move to the location arr[1] and prints the correct value.
but address doesn't changed.
CASE 2:
Now rewritten the above code (removed '&' from print statement)
printf(" %p - %d\n", p, *p);
p = p+1;
printf(" %p - %d\n", p, *p);
output -
0x7ffdb20b9d1c - 2
0x7ffdb20b9d1d - 0
address changed by 1.
and similarly it works correctly when I update the code with p = p+4;
Output -
0x7ffef8735d6c - 2
0x7ffef8735d70 - 3
Address increased by 4.
I am not getting why address is not changed, when I am using '&' in print statement (CASE I).
What is difference between '&p' and 'p' in this case.
OS is Kubuntu and compiler GCC.
p is a variable of type char *
as a char * variable p holds values which represent pointers to characters.
&p is the address where this variable p is stored in memory.
When you write p = p + 1 you change the value of the variable p. But the variable p is the same variable, stored at the same memory, so naturally &p doesn't change.
the &-operator in c gives you the adress where the value is stored. so with &p you get the address where p is stored and NOT the adress of the value p points to. whichs is why the adress in your first case did not change.
case 2: you removed the & so you get the value of the adress where p points to which changes once you increase p.
i hope this is clear now :)
The problem is not what you are doing, but how you are printing the data.
int arr[3] = {2,3,4};
char *p = (char *) arr;
printf(" %p - %d\n", p, *p);
p = p+1;
printf("%p - %d\n", p, *p);
If you substitute the apparitions of &p by just p, then you'll get the results you expected. The problem is that & is read as "get the address of", so &p will return the address in which char * p is stored, ¡and that never changes!
int arr[3] = {2,3,4};
int *p = arr;
printf(" %p - %d\n", p, *p);
p = p+1;
printf("%p - %d\n", p, *p);
That's why your second block of code works. And just above these lines you have something which actually makes more sense, in which p is an int *.
I suggest you take a look at C-Sim (disclaimer: it was created by me), and follow the tutorials. C-Sim will draw a status diagram for code such as the one above.
Hope this helps.
Why does the pointer p always point to its own memory address as an integer in the following example. I can't see where it is initialized and would guess that it would be a garbage value. Can someone show me why it is not a garbage value. By the way I am compiling this in gcc with -std set to c99.
#include <stdio.h>
int main() {
int *p; int a = 4;
p = &a;
*p++;
printf("%d %u\n", *p, p);
}
Your problem (as the other answers point out) is with *p++;. What that says to do is dereference p then increment the address in p.
From what you are seeing, we can assume p comes directly after a in memory
_________________________________________
|something | a | p | something else |
-----------------------------------------
So what ends up happening is p points to a, then is incremented so it points to itself (or more specifically: p stores the address that p is at).
First you need to print a pointer value with %p, and your code has undefined behavior. You move the pointer one place after a and dereference it.
Your code doesn't illustrate the point you (it seems) wanted, the following will:
#include <stdio.h>
int main() {
int *p; int a = 4;
p = &a;
printf("%d %p %p\n", *p, p, &p);
}
It produces something like:
4 0x7fff5c17da44 0x7fff5c17da48
p points to a then *p is the value of a. The value of p is 0x7fff5c17da44 which is the adresse of a and the address of p (&p) is 0x7fff5c17da48.
I'm trying to understand the difference between int a and int *a, my first step was to see the value I could get by printi %p of an int a. Of course the compiler shows warnings, but does complete the job for the following code.
#include <stdio.h>
int main() {
int a;
printf("a - declared");
printf("int a = [%d]\n", a); // example - 1745899614
printf("int a pointer = [%p]\n", a); // example - 0x6810505e
a = 10;
printf("a - initialized to value of 10\n");
printf("int a = [%d]\n", a); // exmaple - 10
printf("int a pointer = [%p]\n", a); // example - 0xa
return 0;
}
And as I've mentioned in the source code, I do get a somewhat satisfactory result of 0xa which is equal to 10 in hexadecimal for the value of %p of an int a. But is it actually the case that int points to to that address, or is this just the compiler trying to make sense of %p in such a case?
Where is the memory allocated for ints? How do I test for that?
To print the address of an object named a, use:
printf("The address of a is %p.\n", (void *) &a);
Merely using %p does not tell printf to print the address of the object you use as the argument. You must use the “address of” operator, &, to take the address. Otherwise, you are passing the value of a to printf, not the address of a.
Additionally, it is proper to convert the address to void *, as shown above, because the %p specifier expects a pointer to void. Other types of pointers often work (or appear to work) in many C implementations, but the technical requirement is that a pointer to void be passed.
I imagine the formater ( in printf ), is just interpreting the memory as it is told to. So yeah, "%p" is for pointer, but you gave it an int. You wanted to give it the address of a:
printf( "%p", &a );
for the whole shabang:
int a = 10;
int *b = &a;
printf("value of a: %d\n", a );
printf("location of a: %p\n", &a );
printf("value of b: %p\n", b );
printf("location of b: %p\n", &b );
printf("dereference b: %d\n", *b );
But is it actually the case that int points to to that address, or is
this just the compiler trying to make sense of %p in such a case?
It's the latter. Compiler tries to interpret the integer as a pointer. When you print the value of a using %p compiler finds that the type of a is int and warns you that it's not a pointer.
To print the address of a use:
printf("int a pointer = [%p]\n", (void*)&a);
If a is a pointer (e..g int *a;) then you need to initialize it with a valid address and then you can print:
printf("int a pointer = [%p]\n", (void*)a);
%p is merely a way to tell printf to print your value as an address memory. You're passing the value of 10to it (the value of a) and you get printed this value in the hexadecimal notation 0xa. There is no special interpretation, it is just a formatting option.
If you want the value of the a's address memory printed you can simply do printf("%p", &a);. &a is the address of a.
Or if you want to use a pointer:
int* p;
p = &a;
printf("%p", p); //Prints the p value, that is the a address. Equivalent to printf("%p", &a).