Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of local variable allocation on the stack

Tags:

c

stack

memory

x86

gcc

Take a look at these two functions:

void function1() {     int x;     int y;     int z;     int *ret; }  void function2() {     char buffer1[4];     char buffer2[4];     char buffer3[4];     int *ret; } 

If I break at function1() in gdb, and print the addresses of the variables, I get this:

(gdb) p &x   $1 = (int *) 0xbffff380 (gdb) p &y $2 = (int *) 0xbffff384 (gdb) p &z $3 = (int *) 0xbffff388 (gdb) p &ret $4 = (int **) 0xbffff38c 

If I do the same thing at function2(), I get this:

(gdb) p &buffer1 $1 = (char (*)[4]) 0xbffff388 (gdb) p &buffer2 $2 = (char (*)[4]) 0xbffff384 (gdb) p &buffer3 $3 = (char (*)[4]) 0xbffff380 (gdb) p &ret $4 = (int **) 0xbffff38c 

You'll notice that in both functions, ret is stored closest to the top of the stack. In function1(), it is followed by z, y, and finally x. In function2(), ret is followed by buffer1, then buffer2 and buffer3. Why is the storage order changed? We're using the same amount of memory in both cases (4 byte ints vs 4 byte char arrays), so it can't be an issue of padding. What reasons could there be for this reordering, and furthermore, is it possible by looking at the C code to determine ahead of time how the local variables will be ordered?

Now I'm aware that the ANSI spec for C says nothing about the order that local variables are stored in and that the compiler is allowed to chose its own order, but I would imagine that the compiler has rules as to how it takes care of this, and explanations as to why those rules were made to be as they are.

For reference I'm using GCC 4.0.1 on Mac OS 10.5.7

like image 950
David Avatar asked Jul 09 '09 05:07

David


People also ask

What order are local variables stored on the stack?

The stack is used for dynamic memory allocation, and local variables are stored at the top of the stack in a stack frame.

Does a local variable allocate space on the stack?

Every time a function is called, the machine allocates some stack memory for it. When a new local variables is declared, more stack memory is allocated for that function to store the variable. Such allocations make the stack grow downwards.

How are local variables allocated?

For local variables, the memory they consume is on the stack. This means that they must have a fixed size known at compile time, so that when the function is called, the exact amount of memory needed is added to the stack by changing the value of the stack pointer.

Which type of variables are stored on stack memory?

Stack memory only contains local primitive variables and reference variables to objects in heap space. Objects stored in the heap are globally accessible whereas stack memory can't be accessed by other threads.


2 Answers

I've no idea why GCC organizes its stack the way it does (though I guess you could crack open its source or this paper and find out), but I can tell you how to guarantee the order of specific stack variables if for some reason you need to. Simply put them in a struct:

void function1() {     struct {         int x;         int y;         int z;         int *ret;     } locals; } 

If my memory serves me correctly, spec guarantees that &ret > &z > &y > &x. I left my K&R at work so I can't quote chapter and verse though.

like image 154
Crashworks Avatar answered Sep 27 '22 21:09

Crashworks


So, I did some more experimenting and here's what I found. It seems to be based on whether or not each variable is an array. Given this input:

void f5() {         int w;         int x[1];         int *ret;         int y;         int z[1]; } 

I end up with this in gdb:

(gdb) p &w $1 = (int *) 0xbffff4c4 (gdb) p &x $2 = (int (*)[1]) 0xbffff4c0 (gdb) p &ret  $3 = (int **) 0xbffff4c8 (gdb) p &y $4 = (int *) 0xbffff4cc (gdb) p &z $5 = (int (*)[1]) 0xbffff4bc 

In this case, ints and pointers are dealt with first, last declared on the top of the stack and first declared closer to the bottom. Then arrays are handled, in the opposite direction, the earlier the declaration, the highest up on the stack. I'm sure there's a good reason for this. I wonder what it is.

like image 32
David Avatar answered Sep 27 '22 20:09

David