19

I'm having simple code as follows:

#include<stdio.h>

int glob;

int main(void)
{
   int a;
   printf("&a is : %p \n", &a);
   printf("glob is : %p \n", &glob);
   return 0;
}

Output of above program is: First run:

&a is : 0x7fff70de91ec
glob is : 0x6008f4

Second run :

&a is : 0x7fff38c4c7ac
glob is : 0x6008f4

I'm studying about virtual & physical addresses. I have following question:

  1. Which is the printed address(physical/virtual) of variable "a"?
  2. If it is virtual then, How it changes in each run of same program? As i understood compiler provides virtual address to variables at compile time?
  3. Why the address of global variable is constant in each run of program?

In executed this program on Linux : 2.6.18-308.el5 x86_64 GNU/Linux

Compiled using : gcc version 4.1.2 20080704 (Red Hat 4.1.2-52)

Jens
  • 69,818
  • 15
  • 125
  • 179
BSalunke
  • 11,499
  • 8
  • 34
  • 68
  • 3
    Your program invokes **undefined behavior**. A `%p` must be given a ptr-to-void, so you must cast to `(void*)` in both printfs. – Jens Apr 05 '13 at 12:09
  • @Jens Wouldn't the argument be implicitly cast to `void *`? – Vilhelm Gray Apr 05 '13 at 12:54
  • 3
    @VilhelmGray implicit conversions take place when a type is expected, but there are no types in a variadic functions. – effeffe Apr 05 '13 at 13:45

4 Answers4

18

Both addresses are virtual.

Modern systems uses stack randomization to prevent so-called stack-smashing attacks, which is why the local variable can change its location every run. However the global variable is stored in the executable and is loaded at the same offset every time.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 9
    It's worth noting that certain other operating systems and some more security minded Linux distributions have PIE (position independent executables) and on those the address of the global variable will change too. – Art Apr 05 '13 at 12:00
  • @Joachim, yes i agree local variables are stored in stack but why it is said that variables are given a specific address at compile time by compiler? – BSalunke Apr 05 '13 at 12:01
  • @BSalunke Local variables are placed at a specific _offset_ from the stack pointer when a function is called. So while the compiler doesn't give it a fixed address the variables still has an address given by the compiler. – Some programmer dude Apr 05 '13 at 12:06
  • @BSalunke Each variable *must* map to an address, how else is the compiler supposed to generate instructions to access it? In some cases it can be absolute addresses (in the process' virtual space) as for globals, for locals it's typically stack-relative addresses. – unwind Apr 05 '13 at 12:06
9

Addresses seen in a program are always virtual and the behaviour described by the OP is a Linux counter-measure to avoid buffer overflow attacks.

Just to try, you can disable it with

sysctl -w kernel.randomize_va_space=0

then run again your program and watch.

The global one is in another space of memory that can't be harmful in an hackish-wise point of view. That's because it is not randomized every time.

Davide Berra
  • 6,387
  • 2
  • 29
  • 50
5

Your program will always see just virtual address.

Real addresses are available only of virtual memory manager in kernel mode.

Globals has same address (until you place other variables before it) because it is created in data segment.

Local variables are always created on stack.

rkosegi
  • 14,165
  • 5
  • 50
  • 83
4

All the addresses seen by program are virtual. However local variables go on stack and global on special area called Data segment. Though variables relative locations are decided at compilation , stack may vary on each run.

Ulka Vaze
  • 196
  • 2