0

How are variables are located in memory? I have this code

int w=1;
int x=1;
int y=1;
int z=1;

int main(int argc, char** argv) {
    printf("\n  w %d",&w);
    printf("\n  x %d",&x);
    printf("\n  y %d",&y);
    printf("\n  z %d",&z);
    return (EXIT_SUCCESS);
}

and it prints this

w 134520852
x 134520856
y 134520860
z 134520864

We can see that when other integer is declare and assigned, the address is moved four positions (bytes I suppose, it seems very logic). But if we don't assign the variables, like in the next code:

int w;
int x;
int y;
int z;

int main(int argc, char** argv) {
    printf("\n  w %d",&w);
    printf("\n  x %d",&x);
    printf("\n  y %d",&y);
    printf("\n  z %d",&z);
    return (EXIT_SUCCESS);
}

it prints this

w 134520868
x 134520864
y 134520872
z 134520860

We can see there are four positions between addresses, but they are not in order. Why is this? How works the compiler in that case?

In case you want to know why I'm asking this, it is because I'm starting to study some security and I'm trying to understand some attacks, for instance, how integer overflow attacks work, and I've been playing with pointers in C to modify other variables by adding more positions than the size of the variable and things like that.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Sfp
  • 539
  • 4
  • 15
  • 1
    Use %p for address. Your variables in the second example will automatically assigned the 0 value. – γηράσκω δ' αεί πολλά διδασκόμε Feb 25 '14 at 23:25
  • 3
    Look for 'bss' in the search box. The difference is between initialized data in the data segment and uninitialized data in the BSS (block started by symbol) segment, which holds zero-initialized data. For example [Why is the BSS segment required?](http://stackoverflow.com/questions/9535250/why-is-the-bss-segment-required) – Jonathan Leffler Feb 25 '14 at 23:27
  • The compiler allocates the variables wherever it chooses. – Jim Balter Feb 25 '14 at 23:32
  • @valter The question isn't about the values of the variables and the code posted doesn't depend on them. – Jim Balter Feb 25 '14 at 23:32
  • 1
    @JimBalter It is an answer to *But if we don't assign the variables* – γηράσκω δ' αεί πολλά διδασκόμε Feb 25 '14 at 23:34
  • After studying things more carefully, you might also (or instead - of BSS) be interested in ASLR -- Address Space Layout Randomization. I'm not sure whether that's a factor in what you're seeing; it is more typically applied to loading shared libraries at different addresses. (Also, it is better to end messages from `printf()` with newlines than to start messages with newlines. It more nearly ensures that the messages are printed in a timely manner.) – Jonathan Leffler Feb 25 '14 at 23:35
  • @valter Well, its not really an answer, but Jonathan's addition made it one I suppose. – Jim Balter Feb 25 '14 at 23:36

2 Answers2

2

Your first example initialises variables, which generates different allocation code. By looking into the assembly file generated by gcc (gas) I get:

    .globl  _w
    .data
    .align 4
_w:
    .long   1
    .globl  _x
    .align 4
_x:
    .long   1
    .globl  _y
    .align 4
 _y:
    .long   1
    .globl  _z
    .align 4
 _z:
    .long   1

And this basically dictates the memory addresses.

Your second example creates uninitialised variables, and as Jonathan said, those go into BSS. The assembler code is:

.comm  _w, 4, 2
.comm  _x, 4, 2
.comm  _y, 4, 2
.comm  _z, 4, 2

And that means you can't guarantee the sequence in which those variables will be located in memory.

rfernandes
  • 1,121
  • 7
  • 9
1

The second set of numbers is also consecutive, just not ordered the same as in the source. I think the reason for this is simply that when you initialize the variables the compiler puts them in order because it maintains the order of initializations, in the second case you just get a random order.

In any case this depends on the compiler; I get the same pattern (ordered, 4 bytes apart) in both cases.

Arkku
  • 41,011
  • 10
  • 62
  • 84