1

Here is an example

#include <stdio.h>

int main()
{
    int a;
    printf("%d\n",&a);
    printf("%p\n",&a);

    return 0;
}

======Output=======

-2054871028                                                                                                                      
 0x7ffd8585280c

Do these two address point to same address in RAM ?

And how can i get the value by using each one of them, especially the second one.

AbyxDev
  • 1,363
  • 16
  • 30
Ritesh95
  • 57
  • 1
  • 6
  • Try printing as %x instead of %d. What do you mean by value? The value of a pointer is its address. – cup Jun 30 '18 at 04:24
  • value of the variable "a". – Ritesh95 Jun 30 '18 at 04:29
  • 1
    As 32-bit hex `-2054871028` is `8585280C`. Printing a pointer with `"%d"` is UB. Printing a non`-void*/character*` with `"%p"` is UB. Do it right with `printf("%p\n",(void*) &a);` Your compiler should have warned. – chux - Reinstate Monica Jun 30 '18 at 04:30

2 Answers2

3

%d format specifier is used to output a signed decimal integer.

From C Standard#7.21.6.1p8

d,i
The int argument is converted to signed decimal in the style [-]dddd. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is 1. The result of converting a zero value with a precision of zero is no characters.

%p prints the pointer.

From C Standard#7.21.6.1p8

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. [emphasis mine]

This statement

    printf("%d\n",&a);

lead to undefined behavior because %d is not valid for printing a pointer.

From C Standard#7.21.6.1p9

If a conversion specification is invalid, the behavior is undefined.282) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

H.S.
  • 11,654
  • 2
  • 15
  • 32
1

When you take the address of the variable a by writing &a, what you're really doing is generating a pointer to a.

%p is designed for printing pointers. You should use %p to print pointers.

%d is not designed for printing pointers. It tries to print their values as signed decimal, which can be confusing (as you've seen), and it may not print the entire value, on a machine where pointers are bigger than integers. (For example, if you try to print pointers with %d in most "64 bit" environments, you can get even stranger results -- and that might be part of what happened here.)

This is an easy mistake to make. Good compilers should warn you about it. Mine says "warning: format specifies type 'int' but the argument has type 'int *'".

But yes, both 0x7ffd8585280c and -2054871028 do "point to the same address in RAM", because they're both the same number, the same address. (Well, they're trying to be the same address. See footnote below.)

I'm not sure what you mean by "And how can I get the value". Are you trying to get the value of the pointer, or the value of what the pointer points to?

You've already got the value of the pointer -- it's the address 0x7ffd8585280c. And since we know it points to the variable a, we know the value it points to, too. Things will be a bit more clear if we do it like this:

int a = 5;
int *ip = &a;
printf("value of pointer: %p\n", ip);
printf("pointed-to value: %d\n", *ip);

Without the explicit pointer variable ip, we could write

int a = 5;
printf("value of pointer: %p\n", &a);
printf("pointed-to value: %d\n", *&a);

But that's pretty silly, because the last line is equivalent to the much more straightforward

printf("pointed-to value: %d\n", a);

(Taking the address of a variable with & and then grabbing the contents of the pointer using * is a no-op: it's a lot like like writing a + 1 - 1.)


Footnote: I said that 0x7ffd8585280c and -2054871028 were the same number, but they're not, they're just trying to be. 0x7ffd8585280c is really -140748133160948, and -2054871028 is really 0x8585280c, which is the lower-order 8 digits of 0x7ffd8585280c. It looks like %p on your machine is printing pointers as 48-bit values by default. I was about to be surprised by that, but then I realized my Mac does the same thing. Somehow I'd never noticed that.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • The 48-bits is not a coincidence but [a limit on virtual memory on current hardware](https://stackoverflow.com/questions/7190708/c-pointer-on-64-bit-machine) – Bo Persson Jun 30 '18 at 12:05
  • @BoPersson I figured it was something like that. ("You mean I can't put 16 exabytes of memory in my computer? Dang."). Thanks for the typo fix, btw. – Steve Summit Jun 30 '18 at 12:16