How to print a pointer address without printf

gal*_*air 2 c arrays printf pointers

I'm doing an exercise in which I need to print the memory (address) of a pointer. It would be easy to do it with printf("%p", ..) but I'm not allowed to use it.

Do you know how I can get the address without using printf()? The only function I can use is 'write'.

Here is the statement of my exercise :

Write a function that takes (const void *addr, size_t size), and displays the memory as in the example. Your function must be declared as follows:

void print_memory(const void *addr, size_t size);
Run Code Online (Sandbox Code Playgroud)
$ cat main.c

void  print_memory(const void *addr, size_t size);

int   main(void)
{    
      int tab[10] = {0, 23, 150, 255,
                     12, 16,  21, 42};

      print_memory(tab, sizeof(tab));
      return (0);
}

$ gcc -Wall -Wall -Werror main.c print_memory.c && ./a.out | cat -e
0000 0000 1700 0000 9600 0000 ff00 0000 ................$
0c00 0000 1000 0000 1500 0000 2a00 0000 ............*...$
0000 0000 0000 0000                     ........$
Run Code Online (Sandbox Code Playgroud)

rsl*_*mos 6

EDIT: I provided this answer before the OP clarified they actually wanted to dump memory contents (before clarifying it they asked for code to act like printf("%p", mem_ptr).

This code should spell out each digit (in hex):

#include <stdint.h>

/* you must provide this function somewhere */
extern void write_char(char);

char hex_digit(int v) {
    if (v >= 0 && v < 10)
        return '0' + v;
    else
        return 'a' + v - 10; // <-- Here
}

void print_address_hex(void* p0) {
    int i;
    uintptr_t p = (uintptr_t)p0;

    write_char('0'); write_char('x');
    for(i = (sizeof(p) << 3) - 4; i>=0; i -= 4) {
        write_char(hex_digit((p >> i) & 0xf));
    }
}
Run Code Online (Sandbox Code Playgroud)

Here, print_address_hex is a basic algorithm for printing digits one at a time (like this one). [to simplify things I didn't care about leading zeros]

The core of the algorithm are the operators >> (acts like binary integer division) and & (acts like binary remainder). [notice that those operators will only work for bases 2, 4, 8, 16, 2^n in general].

I used uintptr_t to make it portable. This type - declared in <stdint.h> - refers to an integral type capable of holding a pointer (architecture independent). We need an integral type so that we can use arithmetic operators (besides + and -, the only valid operators for pointer arithmetic).