Reputation: 31
This was a question asked by an interviewer:
#include<stdio.h>
int main()
{
char *c="123456";
printf("%d\n",c);
return 0;
}
This piece of code always prints a fixed number (e.g. 13451392), no matter how many times you execute it. Why?
Upvotes: 3
Views: 401
Reputation:
Most executable file formats have an option to tell the OS loader at which virtual address to load the executable, For example PE format used by Windows has ImageBase
field for this and usually sets to 0x00400000
for applications.
When the loader first load the executable, it tries load it at that address, if it's not used, it load it at it, which is mostly true, but if it's used. It load it at different address given by the system.
The case here is that the offset to your "12345"
in the data section is the same, and OS loads the image base at the same base address, so you always get the same virtual address, base + offset.
But this is not always the case, one for the given reason above, the base address may be used, alot of Windows DLLs compile using MSVC sets their base address to 0x10000000
, so only one or none is actually loaded at that address.
Another case is when there is address space randomization ASLR, security feature, if it is supported and enabled by the system, MSVC has the linker option /DYNAMICBASE
, the system will ignore the specified image base and will give you different random address on its own.
Two things to conclude:
%p
for printing address, on some systems, for example, int
is 4 bytes and pointers are 8 bytes, part of you address will be chopped.Upvotes: 1
Reputation: 40679
To answer your question, the character string "123456" is a static constant in memory, and when the .exe is loaded, it always goes into the same memory location.
What c
is (or rather what it contains) is the memory address of that character string which, as I said, is always at the same location. If you print the address as a decimal number, you see the address, in decimal.
Of course, as @dasblinkenlight said, you should print it as a pointer, because different machines/languages have different conventions about the size of pointers versus the size of ints.
Upvotes: 1
Reputation: 726919
Your code contains undefined behavior: printing a pointer needs to be done using %p
format specifier, and only after converting it to void*
:
printf("%p\n", (void*)c);
This would produce a system-dependent number, which may or may not be the same on different platforms.
The reason that it is fixed on your platform is probably that the operating system always loads your executable into the same spot of virtual memory (which may be mapped to different areas of physical memory, but your program would never know). String literal, which is part of the executable, would end up in the same spot as well, so the printout would be the same all the time.
Upvotes: 4