众所周知,局部变量位于堆栈上。但是,他们的订单是什么?它们是按照声明的顺序排列的吗?这意味着第一个声明的变量排列在堆栈的较高地址上(堆栈增长到较低的地址)?举个例子:
void foo(){
int iArray[4];
int iVar;
}
在堆栈上,局部变量 - iArray
和iVar
按如下方式排列?
答案 0 :(得分:5)
只有关闭了优化!
一旦优化器掌握了您的代码,所有投注都将被取消。积极优化的常用策略是:
答案 1 :(得分:4)
没有可依赖的规则。除非您开始优化代码,否则大多数编译器都会使用声明顺序。
启用优化可以导致重用堆栈空间,重新排序局部变量,甚至将变量移动到CPU寄存器,因此它们不会再出现在堆栈中。
[编辑]在某些系统上,堆栈会增长到更大的地址。所以它从0x1000开始,下一个地址是0x1001,而不是从0xffff开始,下一个地址是0xfffe。
答案 2 :(得分:1)
最简单的实现使得很容易预测各种变量最终会在堆栈中出现的位置。但是,这些实现还允许某些安全问题(主要是溢出缓冲区和预测额外数据将覆盖的内容,允许注入shellcode)。
由于堆栈的布局是在大多数基于堆栈的语言中定义的实现(从技术上讲,许多此类语言不强制使用堆栈,而是具有易于实现的语义对于堆栈而言,编译器编写者已经不遗余力地使用make it hard to predict the stack layout at runtime。