1

I tried to play around a little bit with pointer for some assigned value of 'i' and what I found out in in that there are two different addresses assigned for declaration %u and %lu,%llu. How is possible that a variable can have two different addresses at the same instance of execution -

#include <stdio.h>
int main(void)
{
  int i;
  float f;
 printf("\nEnter an integer:\t");
 scanf("%d",&i);

  printf("\nValue of address of i=%u",&i);
  printf("\nvalue of address of i=%d",&i);
  printf("\nValue of address of i=%lu",&i);
  printf("\nValue of address of i=%llu",&i);

  printf("\nvalue of i=%d",i);
  printf("\nvalue of i=%u",i);
  printf("\nvalue of i=%lu",i);
  printf("\nvalue of i=%llu\n",i);

}

This is the output -

aalpanigrahi@aalpanigrahi-HP-Pavilion-g4-Notebook-PC:~/Desktop/Daily programs/pointers$ ./pointer001

    Enter an integer:   12

    Value of address of i=1193639268
    value of address of i=1193639268
    Value of address of i=140725797092708
    Value of address of i=140725797092708
    value of i=12
    value of i=12
    value of i=12
    value of i=12

Here we can clearly see that for %u and %d the address is 1193639268 (Though the output of %d and %u might not be equal in all cases) and the output of %lu and %llu is 140725797092708 and what is it's physical significance.

4 Answers4

7

The proper format specifier for printing a pointer is %p.

Using the wrong format specifier, such as %d, %u, %lu, or %llu invokes undefined behavior.

As the the specific behavior you're seeing, a pointer on your particular implementation is probably an 8 byte value, while an int or unsigned int is probably a 4 byte value. As a result, using %d or %u only reads the first 4 bytes of the 8 byte value passed in to the function and prints that value. When you then use %lu or %llu, all 8 bytes are read and printed as such.

Again, because you're invoking undefined behavior, you can't depend on this particular output to be consistent. For example, compiling in 32-bit mode vs 64-bit mode will likely give different results. Best to use %p, and also to cast the pointer to void *, as that is the specific pointer type expected by %p.

dbush
  • 205,898
  • 23
  • 218
  • 273
4

There is only one address. You're using integer printing codes of varying widths, so sometimes you see 32 bits of address, and sometimes you see 64 bits of address. How much is valid depends on your system; on a 32 bit system, printing 64 bits means 32 bits of the value are garbage; on a 64 bit system, printing 32 bits means you're omitting half the pointer.

There is a dedicated format code, %p that's intended for printing pointers, use that, not integer printing codes.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
3

You're using the wrong format specifier, which results in undefined behavior. In this specific case the behavior is that 1193639268 (0x47257D64) is the lower part of 140725797092708 (0x7FFD47257D64)

The correct format specifier for addresses is %p

phuclv
  • 37,963
  • 15
  • 156
  • 475
2

It doesn't. It's just that you are using incorrect format specifiers for pointer types.

The behaviour on doing that is undefined. The output you observe is a manifestation of that undefined behaviour.

Use %p for a pointer, and cast the pointer argument to a const void* type (many compilers are lax on this last point but it's good practice nonetheless).

Bathsheba
  • 231,907
  • 34
  • 361
  • 483