How to printf a memory address in C
Use the format specifier %p
:
printf("variable A is at address: %p\n", (void*)&A);
The standard requires that the argument is of type void*
for %p
specifier. Since, printf
is a variadic function, there's no implicit conversion to void *
from T *
which would happen implicitly for any non-variadic functions in C. Hence, the cast is required. To quote the standard:
7.21.6 Formatted input/output functions (C11 draft)
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.
Whereas you are using %x
, which expects unsigned int
whereas &A
is of type int *
. You can read about format specifiers for printf from the manual. Format specifier mismatch in printf leads to undefined behaviour.
varlotbarnacle
Updated on September 08, 2021Comments
-
varlotbarnacle almost 3 years
My code is:
#include <stdio.h> #include <string.h> void main() { char string[10]; int A = -73; unsigned int B = 31337; strcpy(string, "sample"); // printing with different formats printf("[A] Dec: %d, Hex: %x, Unsigned: %u\n", A,A,A); printf("[B] Dec: %d, Hex: %x, Unsigned: %u\n", B,B,B); printf("[field width on B] 3: '%3u', 10: '%10u', '%08u'\n", B,B,B); // Example of unary address operator (dereferencing) and a %x // format string printf("variable A is at address: %08x\n", &A);
I am using the terminal in linux mint to compile, and when I try to compile using gcc I get the following error message:
basicStringFormatting.c: In function ‘main’: basicStringFormatting.c:18:2: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat=] printf("variable A is at address: %08x\n", &A);
All I am trying to do is print the address in memory of the variable A.
-
Iharob Al Asimi about 9 yearsImportant thing to cast to
void *
-
ryyker about 9 years@Blue Moon - why is it important to cast (void *) ?
-
ryyker about 9 yearsI tested, in a little app, printing address of variable with and without cast but got same result. But clearly the standard's statement ( p The argument shall be a pointer to void ) leaves little room for interpretation. Thank you.
-
chux - Reinstate Monica about 9 yearsSo can all pointers convert to
void *
? I think the answer is yes, except maybe not function pointers. -
P.P about 9 yearsYes, the any object pointer T * can be converted to void * safely and back: C11 draft, 6.3.2.3, 1 pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again. But not function pointers: 6.3.2.3, 8 A pointer to a function of one type may be converted to a pointer to a function of another type and back again.
-
chux - Reinstate Monica about 9 years@Blue Moon This does leave the issue of how to print a function pointer (OP's potential memory address). Cast to
uintmax_t
and hope for the best? -
P.P about 9 years@chux There's no standard way to print a function pointer's address. Casting to
void *
and printing with%p
or as you say can cast touintmax_t
and printing may work in practice. But there's no such guarantee it'll work (neither is it standard conforming). The standard leaves the representation of the function pointers to as implementation defined and there's no guarantee that the function pointer value is some kind of integer. So casting to any integer type may not work. -
chux - Reinstate Monica about 9 years@Blue Moon C11 draft informative J.5.7 Function pointer casts implies that casting to
void *
is a usual extension method to print the function pointer - though not guaranteed to be portable. -
Dan Korn almost 4 yearsCareful with this; it assumes 32-bit pointers,and won't work with 64-bit.