Noidea Noidea - 19 days ago 8
C Question

C: Why the memory addresses of string literals are so different to others?

I noticed that string literals have very different addresses in memory than other constants and variables (Linux OS): they have many leading zeros (not printed).

Example:

const char * h = "Hi";
int i = 1;
printf ("%p\n", h);
printf ("%p\n", &i);


Output:

0x400634
0x7fffc1ef1a4c


I know they are stored in
.rodata
part of the executable. Is there a special way the OS handles it afterwards, so the literals end up in a special area of memory (with leading zeros)? Is there any advantages of that memory location or something special about it?

Answer

Here's how process memory is laid out on Linux (from http://www.thegeekstuff.com/2012/03/linux-processes-memory-layout/):

linux process memory layout

The .rodata section is a write-protected subsection of the Initialized Global Data block. (A section which ELF executables designate .data is its writable counterpart for writable globals initialized to nonzero values. Writable globals initialized to zeros go to the .bss block.).

The picture should explain the numerical values of your addresses.


Note: To comply with the standard, you should cast the int* for "%p" to (void*) or else the behavior is undefined.