2

Since in this example I'm able to read value of integer2 thanks to pointer arithmetic:

#include <stdio.h>

    int main() {
      int integer1 = 1;
      int integer2 = 2;
      int *p = &integer1;
      p++;
      printf("%d\n", *p);
    } 

with output:

$ ./test
2

I was wondering why in this example:

#include <stdio.h>

int main()
{
  int array[2] = {0, 1};
  int variable = 0;
  for(int i = 0; i < 3; i++) {
    printf("%d\n", array[i]);
  }
}

then I'm not able to read the value of variable trying to point the next integer but that's what I get:

0
1
336859392

I tried printing the values of &array[0] &array[1] and &variable and this is what I got:

161695488
161695492
161695480

Not only the address of variable is less than the one of the first elements of the array, but it's not even the previous one.
Why in the first example variables address are contiguous and in the second one not?
There is probably something I don't understand on how variables and buffers are allocated in the stack.

EDIT: I know this should not be done, but I'm trying to understand buffer overflows (more realistically the buffer should be of character, given as input by an user), and the goal should be to alter the value of the variable. So what I'm trying to understand is if it's possible to know exactly where the variable actually is in memory.

EDIT2: Turns out that giving -fno-stack-protector makes it work as expected, so gcc is adding by default some sort of protection in order to avoid buffer overflows

  • 3
    With `p++` you make the pointer go out of bounds of the memory it's supposed to point to, dereferencing the pointer will lead to *undefined behavior*. Same with going out of bounds of arrays, it leads to UB as well. Just don't do that. – Some programmer dude Jan 02 '20 at 15:20
  • 2
    This is *undefined behavior*. – Eugene Sh. Jan 02 '20 at 15:21
  • 1
    Why would you want to do that? – lurker Jan 02 '20 at 15:21
  • How do you know you are not reading `variable`, as opposed to there not being a 0 in it? Either way, since this is all *undefined behavior", there is no explanation. – Scott Hunter Jan 02 '20 at 15:22
  • Refer to eg. [How dangerous is it to access an array out of bounds?](https://stackoverflow.com/questions/15646973/how-dangerous-is-it-to-access-an-array-out-of-bounds). – Sander De Dycker Jan 02 '20 at 15:26
  • 1
    one of the most frequent duplicates - answered again – 0___________ Jan 02 '20 at 15:39
  • Does this answer your question? [How dangerous is it to access an array out of bounds?](https://stackoverflow.com/questions/15646973/how-dangerous-is-it-to-access-an-array-out-of-bounds) – Roberto Caboni Jan 02 '20 at 15:42
  • I know it should not be done, but I'm trying to study buffer overflows, more realistically the buffer should be of character, inputed by an user, and the goal should be to alter the value of the variable. So what I'm trying to understand is where the variable actually is in memory – VariabileAleatoria Jan 02 '20 at 15:49

1 Answers1

3

The placement of local variables is a detail of the implementation. They may be placed in any order it deems appropriate.

Attempting to read past the bounds of an array invokes undefined behavior. The inconsistent results you see are a manifestation of that.

As an example, if I run your first code snippet, I do not get 2 as the output. When printing the addresses of each variable, I get:

&integer1=0x7ffcfa6e8c24, &integer2=0x7ffcfa6e8c20

So in my case the implementation puts integer1 after integer2.

dbush
  • 205,898
  • 23
  • 218
  • 273