Search code examples
cavr

Why would printf with %p pointer format specifier print garbage chars on AVR instead of an address?


I have seen How to find the address of a variable when using AVR? - and the conclusion there is basically:

printf()-debugging on embedded targets is a bit complicated, you need to dig through and figure out if there's code to connect printf() with a serial port, and so on. Also, a full printf() can be a bit heavy, so perhaps you're already using a trimmed-down standard library. It's not the compiler's responsibility, you need to figure out how it's implemented.

... but I cannot really figure out why this problem of mine occurs.

I have a variable which I'd like to serve as an "array of strings", and which I'd like to malloc and realloc:

char** my_array = malloc(sizeof(char*)*1);

Then, I have printf redirected to "print" to USB serial port, and then I read the printouts in serial terminal.

As far as I know, the %p format specifier for printf should print an adress of a variable as a hexadecimal number. And I have a statement like this:

printf("my_array %p\r\n", (void *)&my_array);

I've also tried:

printf("my_array %p\r\n", &my_array);
printf("my_array %p\r\n", my_array);

In all cases, the printout I get is like this:

my_array  ▒▒▒ꓣ▒▒▒▒/▒▒f'w'▒`$▒▒W*▒▒X▒f'w'▒`$▒▒Y*▒▒Z▒f'w'▒`▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒#▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒j▒{▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒i▒z▒▒`$▒▒

... which is, clearly, not a hexadecimal number.

Why does this happen, and what am I doing wrong? And how can I get an address of a variable printed as a hexadecimal number in AVR? If it matters, I use CodeVisionAVR compiler...


EDIT: found this:

https://www.avrfreaks.net/forum/format-specifier-pointers-0

But do people actually use %p and especially on an AVR. On an AVR a pointer is a 16bit unsigned number. I'd generally just use %04X or something myself.

(OK just realised this forum might mean 32bit ARM or UC3 where I guess the pointers are 32 bit? Even so %08X in that case)

... so I just used instead:

printf("my_array %08X\r\n", (void *)&my_array);

... and now I get as printout:

my_array 00003FFB

... but now I have no idea whether this is an actual address :)


Solution

  • You can cast the pointer to a uintptr_t and print that:

    printf("my_array %llu\r\n", (unsigned long long)(uintptr_t)&my_array);