简体   繁体   中英

How will the local variables and arrays stored in stack?

[https://i.stack.imgur.com/kfU6n.png ][1]

#include<stdio.h>
int main()
{
    int x = 23;
    int y = 24;
    int z = 25;
    int asar= 26;
    int a[5];    
    int p = 15;
    int q = 16;
    int r = 17;
    a[11]=56;
    a[10]=57;
    a[9]=58;
    a[8]=59;
    a[7]=60;
    a[6]=61;
    a[5]=62;
  
    printf("\t x=%d, y=%d, z=%d,asar=%d, p=%d, q=%d, r=%d \n", x, y, z, asar, p, q, r);

    return 0;
}

I have tried to cross the bound of array and which causes undefined behavior but here I found that all the values out of the bound of array are copied in a sequence that value of highest index
11 got copied in x (first declaration)
10 got copied in y (second declaration)
9 got copied in z (third declaration)
8 got copied in asar (fourth declaration)
7 got copied in p (fifth declaration)
6 got copied in q (sixth declaration)
5 got copied in r (seventh declaration)

There are altogether 7 other variables other than a and I have crossed limit of a exactly by 7 as such (4+7=11) and I got the output as: x=56, y=57, z=58,asar=59, p=60, q=61, r=62
is there any logic behind this or?
Don't be amazed why I considered the memory allocation in stack because there are 7 variables excluding a and exceeded 7 values are copied one after the other. At least it is true in every case for me when number of extra variables is equal to bound exceed.
Is there any logical explanation regarding this or the question is worthless?

While auto variables are almost always stored on a stack, this isn't enforced by the C standard.

For such an object [with automatic storage duration] that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.

[6.2.4 Storage durations of objects, C11]

The data structure which best fit the description is indeed a stack but it is not defined in the standard, and there are no specific order to store the variables. CPU usually require data to be aligned a certain way to access them quickly, and the compiler may (and will) reorder them to reduce unused addresses. Adding a char somewhere in the code may change the internal order of the variables.

Moreover, trying to access objects from other objects addresses is undefined behaviour. Even if you get "lucky" and get it to work the way you want, it may break later for some seemingly unrelated reasons. For example, by changing the optimization level, the compiler may delete or merge certain variables, or place them in registers that you cannot access. Exploiting undefined behaviour is never a good idea.

If you need to ensure a specific order for your data, you can use a struct , whose order is guaranteed.

As discussed in 6.2.5, a structure is a type consisting of a sequence of members, whose storage is allocated in an ordered sequence , and a union is a type consisting of a sequence of members whose storage overlap.

[6.7.2.1 Structure and union specifiers, C99]

Accessing members through the struct object pointer is valid, but the compiler can insert padding in-between members. The offsetof() macro is necessary to correctly access them. (Related : http://www.catb.org/esr/structure-packing/ )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM