0

The both line of printf should print the address of variable ,right? but they both give different value... Why it so , both should give same value coz memory location allocated to variable a is fixed.

#include <stdio.h> 

void main()
{
    int a = 5;
    int *ptra = &a;
    printf("%d", &a);
    printf("%p", ptra);
}
3
  • 7
    Use %p for both printfs and you should get the correct result. Commented Feb 4, 2022 at 6:17
  • 3
    Printing a pointer using %d is undefined behavior. In other words: It may print any value. Always use %p for pointers Commented Feb 4, 2022 at 6:26
  • 1
    @4386427 And always cast the pointer value to void*. %p specifically requires a void* argument, not a pointer of any type. Commented Feb 4, 2022 at 6:37

5 Answers 5

3

Here's the output of your program on my system:

-12115289320x7ffeb7c9891c

The two outputs are jammed together on one line, making it difficult to tell which is which.

Adding newlines to the output, I get:

344225740
0x7ffc148477cc

(There's no guarantee that a variable will have the same address from one run of a program to the next, and some systems deliberately change memory allocations.)

The %d format specifier requires an argument of type int. The correct format specifier for a pointer value is %p, and it requires an argument of type void*. Using inconsistent types, as you've done in your program, causes undefined behavior. At best, on many systems pointers are 64 bits and int is 32 bits, so %d can't possibly show an entire pointer value. It might show part of the pointer value, it might show garbage, or it might crash.

The %p format typically uses hexadecimal, but the format is implementation-defined.

Here's a corrected version of your program:

#include <stdio.h> 
int main(void)
{
    int a = 5;
    int *ptra = &a;
    printf("%p\n", (void*)&a);
    printf("%p\n", (void*)ptra);
}

and the output on my system:

0x7ffd62a733ec
0x7ffd62a733ec

You'll see different output, but the two lines should match each other.

Note: void main() is incorrect; the correct declaration is int main(void).

Sign up to request clarification or add additional context in comments.

Comments

1

They are the same number. You're printing one in decimal form, the other in hexadecimal form.

#include<stdio.h> 
int main(int argc, char **argv)
{
    int a=5;
    int *ptra=&a;
    printf("%p\r\n",&a);
    printf("%p\r\n",ptra);
    return 0;
}

prints

0x7ffc8e4cb974
0x7ffc8e4cb974

for me

3 Comments

The \r is unnecessary. If you're on a system that uses CR-LF line endings, a simple \n will be translated as needed. If you're on a system that uses just LF, the \r is incorrect.
printing pointers with %d is UB
updated the code to remove %d
0

This happens due to the difference in format strings.

%d    takes 32 bits and displays it as a signed value  123
%p    takes a pointer and display it in address format    0fef:0004

Actual value is same but there is difference of interpreting the value.

2 Comments

%d processes an int — these days, outside of embedded systems, an int is usually 32-bits, not 16-bits (though that is officially a possibility). And the address format you show is unusual but not wrong — what %p produces is implementation-defined.
Thanks for input I will edit my answer
0

As already mentioned in the answer from Keith Thompson (https://stackoverflow.com/a/70982344/4386427) the reason is that you are printing an integer value by using %d but the argument isn't an integer - it is a pointer value. Providing an argument with a type that doesn't match the format specifier (i.e. providing a pointer value for %d) leads to undefined behavior which means that it may print any value, text or even nothing.

All that is already well covered by Keith Thompson (https://stackoverflow.com/a/70982344/4386427)

I just like to add that in case you actually want to print a decimal integer representation of the pointer value, you can use the types intptr_t or uintptr_t. Like:

#include <stdio.h> 
#include <inttypes.h> 
int main(void)
{
    int a = 5;
    int *ptra = &a;
    printf("%p\n", (void*)&a);
    printf("%p\n", (void*)ptra);
    
    intptr_t dptr = (intptr_t)(void*)ptra;
    uintptr_t uptr = (uintptr_t)(void*)ptra;

    printf("A signed integer representation of the same pointer in decimal        : %" PRIdPTR "\n", dptr);
    printf("An unsigned integer representation of the same pointer in decimal     : %" PRIuPTR "\n", uptr);
    printf("An unsigned integer representation of the same pointer in hexadecimal : %" PRIxPTR "\n", uptr);

}

Possible output:

0x7ffcaceba19c
0x7ffcaceba19c
A signed integer representation of the same pointer in decimal        : 140723209609628
An unsigned integer representation of the same pointer in decimal     : 140723209609628
An unsigned integer representation of the same pointer in hexadecimal : 7ffcaceba19c

Comments

0

Using %d escape sequence in your first printf is converting your reference from hexadecimal to decimal, i.e, (x)16 --> (x)10.

So your code should be:

#include<stdio.h>

int main(void)
{
    int a=5;
    int *ptra=&a;
    printf("%p\n",&a);
    printf("%p",ptra);
    return 0;
 }

Output: (may vary on your machine)

000000000061fe14
000000000061fe14

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.