Printing values, pointers and pointers to values [closed] - c

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.

Related

dereferencing pointer to a pointer with one Asterisk [duplicate]

This question already has answers here:
Pointer to pointer clarification
(16 answers)
Closed 1 year ago.
#include <stdio.h>
int main(){
int integer = 300;
int* p = &integer;
int** pp = &p;
printf("*pp = %i", *pp);
}
My question is what is actually *pp? What does it mean to print the value in the address of *p ?
It is a reference to the integer converted to an integer value.
To print the reference you should use %p format specifier instead of the %i format specifier.
[pp] -> [p] -> [integer]
If you modify the program you can see the references and how they are chained:
int main()
{
int integer = 300;
int* p = &integer;
int** pp = &p;
printf("pp = %p *pp = %p\n",(void *)pp, (void *)*pp);
printf("&integer = %p &p = %p\n", (void *)&integer, (void *)&p);
}
pp = 0x7fffb6adc7d8 *pp = 0x7fffb6adc7e4
&integer = 0x7fffb6adc7e4 &p = 0x7fffb6adc7d8
#include <stdio.h>
int main(){
int integer = 300;
int* p = &integer;
int** pp = &p;
printf("**pp=%d\n", **pp);
printf("*p=%d\n", *p);
printf("*pp = %p\n", *pp);
printf("p=%p\n", p);
printf("&integer=%p\n", &integer);
printf("&(*p)=%p\n", &(*p));
printf("pp=%p\n", pp);
printf("&p=%p\n", &p);
}
Since &(*p) is simply p, yes *pp is the address of *p.
Since %i is integer but what you want to print is pointer. So I changed it to %p.
I'm not a pro in C programming, but I believe I have a decent knowledge of pointers.
So, to understand what is *pp, you need to understand what is * operator used for?
It is no doubt used for multiplication, but it is also used for pointer de-referencing.
So when I say *pp, it means the value of pp i.e. what is stored in pp. Each defined variable in C will have a memory space of its own. So *pp means what is stored in the memory space that was given to the variable pp.
In your case,
int integer = 300;
A variable of type integer named integer is declared and given the value 300
int* p = &integer;
A pointer that needs to point to an integer variable is declared and given the address of integer.
int** pp = &p;
A pointer that needs to point to an integer variable is declared and given the address of p
printf("*pp = %i", *pp);
*pp means printing the value which is stored in pp i.e. address of p
**pp means printing the value which is stored in the value which is stored in p i.e. 300
As I explained earlier, each variable has a memory space of its own, and each memory space will have an address assigned to it, so that it can be identified (the way we have an email address which is used to contact us via email or a postal address which is used to contact us via post).
Hope this answers your question. Do ask follow-up questions if any.
Cheers..!!

Can someone will please explain the output of this program?

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.

pointer arithmetic in C while working with array

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.

Integer Pointer Subtraction

I've written a few lines of code predominantly from a book that gets you to declare an integer array, then subtract and pass two addresses from the array to another integer, in order to pass into a printf statement. I'm not sure why, but my actual pointers: aPointer and bPointer seem to be 8 bytes, which poses a problem when I try and pass the subtracted addresses to an integer.
I then changed the latter to a long. The errors are not present in Xcode now, but I cannot print the address of pointerSubtraction properly using the %p specifier which does indeed expect an int and not a long.
int arrayOfInts[10];
for (int i = 0; i < 10; i++) {
arrayOfInts[i] = i;
printf("%d", arrayOfInts[i]);
// prints out 0123456789
}
printf("\n");
int *aPointer = &arrayOfInts[1]; // get address of index 1
int *bPointer = &arrayOfInts[7]; // get address of index 7
long pointerSubtraction = bPointer - aPointer; // subtract index 7 with 1
printf("The size of aPointer is %zu bytes \n", sizeof(aPointer));
printf("The size of aPointer is %zu bytes \n", sizeof(bPointer));
printf("The address of aPointer is %p \n", aPointer);
printf("The address of bPointer is %p \n", bPointer);
printf("The address of final is %p \n", pointerSubtraction);
printf("The value of pointerSubtraction is %ld \n \n", pointerSubtraction);
You might like to use a variable typed ptrdiff_t to store the difference of two pointer values, two addresses.
To printf() out a ptrdiff_t use the length modifier "t". As ptrdiff_t is a signed integer use the conversion specifier "d".
#include <stddef.h>
#include <stdio.h>
int main(void)
{
int a = 0;
int b = 0, * pa = &a;
ptrdiff_t ptr_diff = pa - &b;
printf("pd = %td\n", ptr_diff);
return 0;
}
Also the conversion specifier "p" is only defined for pointers to void. So the printf() calls shall look like:
printf("The address of aPointer is %p \n", (void *) aPointer);
printf("The address of bPointer is %p \n", (void *) bPointer);
Also^2 : The result of adding or substrating a value v from a pointer p is only a valid address if the result pv of the operation still refers to (an element/member of) the object the original pointer p pointed to.
In your code aPointer is the value pointed by *aPointer. Same thing for bPointer.
As the comment says pointerSubtraction is the value obtained by the subtraction, not the address.

What is the meaning of printf("%p", int 1)?

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).

Resources