Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You see, when you allocate a variable like this, it lands on the stack. Stack holds small packages of information about local variables in each function you call, to say it in simple words. The runtime is able to check, whether you exceed the bounds of allocated stack, but not if you write some data in the invalid place on the stack. The stack may look like the following:</p> <p>[4 bytes - some ptr][4 bytes - A's first element][4 bytes - A's second element] ...</p> <p>When you try to assign to -1th element of an array, you actually attempt to read four bytes preceding the array (four bytes, because it's an int array). You overwrite some data held on stack - but that's still in valid process's memory, so there are no complaints from the system.</p> <p>Try running this code in release mode in Visual Studio:</p> <pre><code>#include &lt;stdio.h&gt; int main(int argc, char * argv[]) { // NEVER DO IT ON PURPOSE! int i = 0; int A[5]; A[-1] = 42; printf("%d\n", i); getchar(); return 0; } </code></pre> <hr /> <p><b>Edit:</b> in response to comments.</p> <p>I missed the fact, that A is global. It won't be held in stack, but instead (mostly probably) in .data segment of the binary module, however the rest of explanation stands: A[-1] is still within process's memory, so assignment won't raise AV. However, such assignment will overwrite something, that is before A (possibly a pointer or other part of the binary module) resulting in undefined behavior.</p> <p>Note, that my example may work and may not, depending on compiler (or compiler mode). For example, in debug mode the program returns 0 - I guess, that memory manager inserts some sentry data between stack frames to catch errors like buffer over/underrun.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload