Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于C语言中堆栈分配的问题_C_Memory Management_Stack - Fatal编程技术网

关于C语言中堆栈分配的问题

关于C语言中堆栈分配的问题,c,memory-management,stack,C,Memory Management,Stack,下面的代码段是有意访问t[4]之后的下一个sizeof(int)字节,因此我知道这里出现了错误。我只是在做一个实验,看看编译器如何处理堆栈分配 int t[5], i; for (i = 0; i <= 5; i++) { t[i] = 0; } intt[5],i; 对于(i=0;i访问t[5]是一种未定义的行为。最后一项是t[4](t[0],t[1],t[2],t[3],t[4])没有t[5] 通过未定义的行为,任何事情都可能发生。它可能会给出预期的结果或完全混乱 我的问题是

下面的代码段是有意访问
t[4]
之后的下一个sizeof(int)字节,因此我知道这里出现了错误。我只是在做一个实验,看看编译器如何处理堆栈分配

int t[5], i;

for (i = 0; i <= 5; i++) {
   t[i] = 0;
}
intt[5],i;

对于(i=0;i访问
t[5]
是一种未定义的行为。最后一项是
t[4]
t[0],t[1],t[2],t[3],t[4]
)没有
t[5]

通过未定义的行为,任何事情都可能发生。它可能会给出预期的结果或完全混乱

我的问题是,为什么会有这种不同的行为


正如我之前所写的,你不能期望任何东西。即使你在同一台机器上多次尝试也可能得到另一个结果。

你正在处理未定义的行为。编译器不需要按顺序排列自动变量(如源代码中所示)。其中一些可能位于寄存器中,或者它们可能以不同的方式排序,例如,如果偏移量较小,则更便宜

这种要求只存在于结构的成员(成员之间有任意填充)

有填充物吗

是的,编译器将遵守每种类型的对齐要求,并相应地放置变量

顺序是否总是与源代码中的顺序相同


不,但这是许多漏洞攻击所依赖的。缓冲区溢出可能会覆盖相邻的变量并危及整个程序的执行。

另一个人说,为什么从标准的角度来看,您会出现这种行为,我将说明编译优化和执行代码后可能发生的情况

第一个:循环可能展开并执行6次:

t[0] = 0;
t[1] = 0;
t[2] = 0;
t[3] = 0;
t[4] = 0;
t[5] = 0;
i = 6;
这是允许优化的,这就是可能发生的。更多:如果以后不使用
i
,则可以将其完全删除

Second:编译器可以在寄存器中保留
i
,而不进行任何堆栈分配

第三个:它可以在堆栈上以任何顺序放置变量。对于变量在内存中的保存顺序(以及它们的位置)没有实际要求

如何知道发生了什么?查看生成的程序集。这是知道发生了什么的唯一方法


顺便说一句:无限循环并不总是发生在Windows上。事实上,我无法强迫您的代码逐字成为无限循环。

C
和C++之间有区别。请不要将这两个问题都加上标签。“我认为堆栈分配应该以相同的方式发生。”-你为什么这么认为?这完全是一个实现细节,而不是语言定义的任何方式。你为什么认为无休止循环的原因是赋值修改
i
?它也可能是编译器知道
i你在不同平台上使用不同的编译器,从而定义了不同的行为d behavior=任何事情都可能发生。您可以看出,在这两种情况下,任何事情都确实发生了,因此该行为符合预期(没有预期的行为)调查为什么不确定的行为在特定的系统中导致特定的结果,在特定的时间点,这只是没有意义的练习。@ GARF365:C++标准不能解释它,但是肯定不是没有什么可以。@本杰明德利,是的,但是为什么?为什么我应该知道如果我做了不确定的事情会发生什么?lfawi:我不知道。也许你对编译器的工作方式感兴趣。@BenjaminLindley它不是关于编译器如何工作的。它是关于编译器如何处理你不应该使用的东西:)它甚至不应该被记录,如果编译器在下一版本中改变这种行为,你甚至不能在法庭上向编译器提起诉讼:)@AlexandruPele也许问题只是。。。措辞不好。在我看来,你们的要求是方向性的,但适用于变量和“相同的代码,不同的编译器,不同的平台”范围。谢谢!我没有真正考虑编译器优化或栈中的顺序不一定相同的事实。