One of my friends gave me this problem and asked me to help with it: Which will be the address memorated in pointer p after running this code?
unsigned * p = (unsigned*)1000;
p = 10;
I just went on CodeBlocks and added to this exercise printf("%u", p);
and the answer was 1040.
What is (unsigned*)1000
, what does it mean? Is printf("%u", p)
the right way of printing the memorated address or is there another syntax/another format specifier that needs to be used? And, why is the answer 1040, and not 1010?
The main problem, the only lines that were given were:
unsigned * p = (unsigned*)1000;
p = 10;
Based on these, I did a little google research and I think that the right way of getting the address is to put printf("%u", p);
. Even if this is correct and this is the right syntax, I still can't understand the process behind this addition.
CodePudding user response:
Pointers themselves aren't "signed" or "unsigned" in the way that integer values are.
What you do with the definition of p
is to define a pointer variable named p
, it points to an unsigned int
value, and you say that it will point to the address 1000
(which for most systems will make no sense).
As for p = 10
that make p
point to ten unsigned int
elements further away from its original position. Assuming the common sizeof(unsigned int) == 4
then after the increment p
will point to the address 1040
(1000 (10 * sizeof(unsigned int))
).
And (unsigned*)1000
is a normal cast. It tells the compiler that the value 1000
is a pointer to an unsigned int
. As said above, this makes no sense on most systems.
CodePudding user response:
unsigned * p = (unsigned*)1000
This is an implementation-defined conversion from integer to a pointer. If/how it will work depends on the target system and compiler port. You will end up with address1000
=0x3E8
. By convention, addresses are always written in hex.p = 10;
This might potentially invoke undefined behavior. Strictly speakingp
has to point on an allocated array or you can't do pointer arithmetic on it. In practice most compilers provide a well-defined compiler extension for such arithmetic or otherwise it becomes annoying to write low-level C code.As for what it does, it is pointer arithmetic (look up the term in your beginner-level learning material). Essentially the whole code is equivalent to
unsigned* p = (unsigned*)(1000 10*sizeof(int));
.-
Is printf("%u", p) the right way of printing
No, it is wrong and undefined behavior. Please note that
unsigned
equalsunsigned int
but you aren't printing what the pointer points at, you are printing the pointer address itself.You need to print pointer addresses like this:
printf("%p", (void*)p)
. Always with%p
always by casting tovoid*
. You should get 0x410 as output.
CodePudding user response:
There already are great answers pertaining to pointer arithmetic, so I'd focus on the other part of your questions.
First Question:
Is printf("%u", p) the right way of printing the memorated address
Answer: No.
Second Question:
or is there another syntax/another format specifier that needs to be used?
Answer:
Yes, the correct format specifier is %p
, and the pointer must be cast to void *
.
From C11:
p
The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.
printf("%p", (void *) p);
And as %p
expects a void
pointer, passing it a pointer to any other type invokes undefined behaviour.
From C11:
7.21.6.1 The fprintf function
If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.