2

I am trying to learn operating systems. At present i am in virtual addressing. What book says that if we have one static variable and one local variable and we update them and sleep for some time and try to print their addresses then across multiple such processes running one will get same memory address.

This is because each process feel like it has whole memory and has no control of physical memory so address will remain same among various process running at the same time. I understand this but when i run my program i am getting same address across static variables but different across local variables. With my little operating systems knowledge i am not able to understand why this is happening. This is my code

int staticvar = 0;

int main(int argc, char const *argv[])
{
  int localvar = 0;
  staticvar += 1;
  localvar += 1;
  sleep(10);
  printf("static address: %x, value: %d\n", &staticvar, staticvar );
  printf("static address: %x, value: %d\n", &localvar, localvar );
  return 0;
}

This is my output when i run three different processes simultaneously.

./a.out 
static address: 60104c, value: 1
static address: 67c6128c, value: 1

./a.out 
static address: 60104c, value: 1
static address: 89e2c11c, value: 1

./a.out 
static address: 60104c, value: 1
static address: 226e03dc, value: 1
shivams
  • 2,597
  • 6
  • 25
  • 47

2 Answers2

3

Local variables are allocated on the stack frame of the function called. The stack frame is referenced through the stack pointer (SP) register which is initialized by the OS upon start of the process. The program uses the SP to dynamically allocate stack space and look up the values stored there. So this type of access is prepared to use a dynamic address, and knowing that, the OS can choose to initialize the process' stack frame wherever it sees fit best in the current context.

"Static" variables, on the other hand, are usually referenced by constant addresses from the compiled (assembler) code. That's why they must reside at a known-at-compile-time location.

Edit:

As someone noted, the value of the SP changes through program execution, depending on stack usage. Therefore, if you call the same funtion from different parts of the program, the address of the local variable may even be different each time.

JimmyB
  • 12,101
  • 2
  • 28
  • 44
0

First, int staticvar = 0; defined by you is called global variable not really a static variable. To define static variable you must add static keyword while declaring the variable, e.g. static int staticvar

Now, if you see the assembly code of your C file, you'll notice that staticvar has been referenced at compile time itself. That is the reason, you're seeing the same memory location for staticvar all the time. Same goes true for, if you have global/static variable defined also.

However, the local variable gets the memory reserved at run time in stack, which OS kernel will have control. That is why you're seeing different memory location at every run.

And this behaviour holds good even if you don't put sleep() in your code.

        .file   "test11.c"
        .local  staticvar
        .comm   staticvar,4,4
        .section        .rodata
        .align 8
.LC0:
        .string "static address: %x, value: %d\n"
.LC1:
        .string "local address: %x, value: %d\n"
        .text
.globl main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $32, %rsp
        movl    %edi, -20(%rbp)
        movq    %rsi, -32(%rbp)
        movl    $0, -4(%rbp)
        movl    staticvar(%rip), %eax
        addl    $1, %eax
        movl    %eax, staticvar(%rip)
        movl    -4(%rbp), %eax
        addl    $1, %eax
        movl    %eax, -4(%rbp)
        movl    $3, %edi
        movl    $0, %eax
        call    sleep
        movl    staticvar(%rip), %edx
        movl    $.LC0, %eax
        movl    $staticvar, %esi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf
        movl    -4(%rbp), %edx
        movl    $.LC1, %eax
        leaq    -4(%rbp), %rcx
        movq    %rcx, %rsi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-11)"
        .section        .note.GNU-stack,"",@progbits
Pawan
  • 1,537
  • 1
  • 15
  • 19
  • Everything in file scope has *static storage duration* by default. Adding `static` to a global variable changes its *linkage*, which is a separate problem. – EOF Aug 03 '15 at 08:36
  • @EOF, I am very much aware that irrespective of `static` keyword global/static variables are treated as same. Only the visibility of the variable gets changed. However, I also understand when people ask, we sometime have to aligned to what common nomenclatures are. Can you please show a reference of any book where someone has mentioned a global variable (without static keyword) and called it as static variable? – Pawan Aug 03 '15 at 08:42
  • Since the question really relates to the storage duration of objects, and the objects the OP asked about *do* have static storage duration, claiming they are "not really a static variable" is at best confusing and unhelpful. Better to cite the C-standard (C11 draft standard §6.2.4 Storage durations of objects). Don't unnecessarily drag linkage into this. – EOF Aug 03 '15 at 08:47
  • @Pawan: the C standards all use the term "static storage duration" to characterise variables declared at file scope, whether they have internal or external linkage. – Peter Aug 03 '15 at 10:27