简体   繁体   English

局部变量和数组将如何存储在堆栈中?

[英]How will the local variables and arrays stored in stack?

[https://i.stack.imgur.com/kfU6n.png ][1] [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) 11被复制到x中(第一个声明)
10 got copied in y (second declaration) 10被复制到y (第二次声明)
9 got copied in z (third declaration) 9被复制到z中(第三次声明)
8 got copied in asar (fourth declaration) 8被复制到asar (第四次声明)
7 got copied in p (fifth declaration) 7被复制到p中(第五次声明)
6 got copied in q (sixth declaration) 6被复制到q中(第六次声明)
5 got copied in r (seventh declaration) 5被复制到r中(第七次声明)

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除了a之外,总共还有 7 个其他变量,我已经将a限制恰好超过了7 个(4+7=11),我得到的输出为: 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.不要惊讶我为什么考虑堆栈中的内存分配,因为除了a之外有7 个变量,超过7 个值被一个接一个地复制。 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.虽然auto变量几乎总是存储在堆栈中,但 C 标准并未强制执行此操作。

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] [6.2.4 对象的存储期限,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. CPU 通常要求数据以某种方式对齐以快速访问它们,并且编译器可能(并且将)重新排序它们以减少未使用的地址。 Adding a char somewhere in the code may change the internal order of the variables.在代码中的某处添加char可能会改变变量的内部顺序。

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.如果您需要确保数据的特定顺序,您可以使用struct ,它的顺序是有保证的。

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.2.5 中所讨论的,结构是由一系列成员组成的类型,其存储按有序序列分配,而联合是由一系列成员的存储重叠组成的类型。

[6.7.2.1 Structure and union specifiers, C99] [6.7.2.1 结构和联合说明符,C99]

Accessing members through the struct object pointer is valid, but the compiler can insert padding in-between members.通过struct对象指针访问成员是有效的,但编译器可以在成员之间插入填充。 The offsetof() macro is necessary to correctly access them. offsetof()宏是正确访问它们所必需的。 (Related : http://www.catb.org/esr/structure-packing/ ) (相关:http: //www.catb.org/esr/structure-packing/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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