0

I am using a void pointer which is assigned to a string. But it is returning me an incorrect address. The way I verified the address of my void pointer was through checking in the elf file. elf file denotes a different address & printf is showing different address.

void *str;
str = "TestString";
printf("%p",str);

Moreover if I use this code twice , it prints the same address. Which makes me believe that it definitely isn't address.

void *str;
str = "TestString";
printf("%p\n",str);
void *str2;
str2 = "TestString";
printf("%p",str2);

Can someone please tell me what exactly is it printing & how can I get the address ?

Cool Camel
  • 57
  • 6
  • How do you know the address is wrong? For the second question read this: https://stackoverflow.com/questions/11399682/c-optimisation-of-string-literals. – Jabberwocky Aug 23 '22 at 12:56
  • @Jabberwocky like I said , address in `.elf` file for str is different. – Cool Camel Aug 23 '22 at 12:57
  • 3
    String literals with the same content can be stored at the same address, as you demonstrated. I don't see how you can diagnose the address as “wrong”. Searching through the ELF file won't help with runtime relocation and ASLR — address-space layout randomization. – Jonathan Leffler Aug 23 '22 at 12:59
  • Admittedly I don't know much about the ELF file format, but you can easily add 2-3 lines in your program which will show that the address is indeed correct – Jabberwocky Aug 23 '22 at 12:59
  • So actually I thought that the address is wrong because when I pass this VOID pointer to another function it is unable to do computations on this address but when I use a `char str[] = "TestString"` and pass it as a pointer to another function it is able to perform computations correctly. Note in case of `char str` address range is very different than void pointer. @JonathanLeffler – Cool Camel Aug 23 '22 at 13:04
  • @Jabberwocky thanks , I verified through gdb that the address of void pointer is correct and is actually storing "TestString" , but I have no idea why void pointer's address is not working but character array's address works. – Cool Camel Aug 23 '22 at 13:06
  • Notably , void pointer's address goes into a totally different range / section for some reason. – Cool Camel Aug 23 '22 at 13:08
  • 1
    @CoolCamel — I can't see your non-working code. Unless you use GCC, you can't do pointer arithmetic on void pointers. I think there may be a typo in your comment about “`char str` address”. I don't understand what you are saying. – Jonathan Leffler Aug 23 '22 at 13:10
  • Ah I see, so it is possible that there is some pointer arithmetic done in my function due to which void pointer fails ! – Cool Camel Aug 23 '22 at 13:12
  • @JonathanLeffler what do you mean by "unless you use GCC" ? GCC allows void pointer arithmetic ? – Cool Camel Aug 23 '22 at 13:15
  • @CoolCamel yes, [it does](https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html), This is done by treating the size of a void or of a function as 1. – David Ranieri Aug 23 '22 at 13:18
  • GCC allows pointer arithmetic on `void *` even though the C standard does not allow it. There are reasons why it does it. (Clang probably allows it too for compatibility with GCC). – Jonathan Leffler Aug 23 '22 at 13:18

1 Answers1

1

Compilers commonly implement something called "string pooling", meaning that identical string literals are stored at the same address, in order to save memory. Which makes perfect sense since they are read-only anyway. It is easy enough to verify that this is the case by checking the disassembly generated by any compiler.

For example gcc x86 only allocates a single string literal in your example. Even with optimizations disabled, there's only a single .string "TestString" present in the disassembly.

If you for some reason need unique addresses, use variables instead:

const char str[] = "TestString";
printf("%p\n",str);
const char str2[] = "TestString";
printf("%p",str2);
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • can you please explain how typecasting is creating unique addresses ? – Cool Camel Aug 23 '22 at 17:10
  • @JonathanLeffler Regarding the edit, I belive that casting away const is "more UB" than passing the wrong pointer type to printf. – Lundin Aug 24 '22 at 06:25
  • @CoolCamel What casting? I simply declared two arrays which contains the actual strings, instead of having two pointers merely pointing at string literals. – Lundin Aug 24 '22 at 06:26