1

I am a first year student in C programming so my skill/knowledge is limited. I am trying to create my own implementation on printf, but I am having trouble with retrieving and printing the address of a variable. With printf, its possible to output the address of a variable with %p, i need to replicate %p somehow.

When storing the address of a variable, the data type is int*, and I cannot figure out how to write this address to the screen(stdout).

For Example:

int i        = 123;
int *address = &i;

Now how would I output address(not the value at i)? I have tried using the original printf format specifiers for testing purposes. I tried using %x, %s, %d, %lu... it all gives me an error as I am trying to output an int*(integer pointer).

Can anyone assist me in outputting the address?

Community
  • 1
  • 1
Kbam7
  • 324
  • 2
  • 15

2 Answers2

5

You can only inspect the bits of the pointer and print those, using the type unsigned char:

unsigned char* a = ( unsigned char* )address;
for( size_t i = 0 ; i < sizeof( address ) ; i++ )
     printf( "%hhu" , a[i] );

Another option, if the pointer is a pointer to an object, is to cast the pointer to types: intptr_t or uintptr_t, but the availability of those types is implementation defined.

2501
  • 25,460
  • 4
  • 47
  • 87
4

If it's for the address of an object you could do the following:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
  int a;
  uintptr_t uip = (uintptr_t) ((void*) &a);
  printf("address of a = 0x%"PRIXPTR, uip);
}

To print the address of a function you need to go as proposed here.

Community
  • 1
  • 1
alk
  • 69,737
  • 10
  • 105
  • 255
  • I didn't find anything that would prohibit casting function pointers to uintptr_t. Did I miss something? – 2501 May 27 '16 at 10:45
  • 1
    I already did: *Any pointer type may be converted to an integer type.* Since a distinction is made in other rules between object and function pointer types, I think *any pointer type* applies to both. – 2501 May 27 '16 at 10:47
  • 1
    @2502: Ok, got it: `intptr_t` and `uintptr_t` are guaranteed by the Standard only to hold the value of a valid `void*` (7.20.1.4/1). A function may not be converted to a `void*`. – alk May 27 '16 at 10:52
  • @2501: Sry, for misspelling your name. Interesting typo however ... ;-) – alk May 27 '16 at 10:59
  • So I deduce: Casting to void* previously is obsolete and you simply could have `(uintptr_t) &a;`... – Aconcagua May 27 '16 at 11:01
  • @Aconcagua: "*Casting to void\* previously is obsolete*" it isn't. Please see my comment above quoting the C Standard. – alk May 27 '16 at 11:22
  • @alk I deduced from 2501 citation: *"Any pointer type may be [...]"* - the void* part in your comment is in my eyes rather a size guarantee: It can hold a valid void*, thus can hold any other valid pointer, too, as long as it is convertible to void* (and thus excludes function pointers). – Aconcagua May 27 '16 at 11:37