How to printf a memory address in C

126,737

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.

Share:
126,737
varlotbarnacle
Author by

varlotbarnacle

Updated on September 08, 2021

Comments

  • varlotbarnacle
    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
    Iharob Al Asimi about 9 years
    Important thing to cast to void *
  • ryyker
    ryyker about 9 years
    @Blue Moon - why is it important to cast (void *) ?
  • ryyker
    ryyker about 9 years
    I 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
    chux - Reinstate Monica about 9 years
    So can all pointers convert to void *? I think the answer is yes, except maybe not function pointers.
  • P.P
    P.P about 9 years
    Yes, 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
    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
    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 to uintmax_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
    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
    Dan Korn almost 4 years
    Careful with this; it assumes 32-bit pointers,and won't work with 64-bit.