我读到了检测堆栈增长检测问题的不同响应,我理解,在现代架构中,堆栈可能会随机增长,可能会在堆外创建,依此类推。
但是,在这个经典的访谈问题中,我想了解为什么人们使用函数调用而不是在同一函数中比较2个局部变量。 我认为必须有一些特殊的理由这样做,但不是一个C /低级开发人员[Java :)],我只是在猜测。
这是我试过的代码:
void sub (int *a) { int b; int c; printf ("a:%dn", a); printf ("b:%dn", &b); printf ("c:%dn", &c); if (&b > a) { printf ("Stack grows up.n"); } else { printf ("Stack grows down.n"); } } int main (void) { int a; int b; sub (&a); printf ("nHere we go again!!n"); if (&b > &a) { printf ("Stack grows up.n"); } else { printf ("Stack grows down.n"); } return 0; }
我还发现这篇文章试图优化我不理解的解决方案: http : //www.devx.com/tips/Tip/37412
PS:从对这个和其他线索的不同反应来看,似乎问题本身是有缺陷/不相关的,作为面试问题它可能会重新执行不正确的假设,除非有人研究答案!
谢谢!
在单个堆栈框架内,编译器可以根据需要自由地对局部变量进行排序,因此代码如下:
int i; double j;
在j
之前或之后可能有i
。 只要编译生成正确的代码来访问变量,它就可以去任何地方。
实际上,除非你使用address-of运算符&
(或者必须得到地址),否则变量可能永远不会在堆栈上。 它可以在呼叫期间存储在寄存器中。
但是,堆栈帧本身的放置顺序是受限制的,因为如果它们出现故障,函数返回将无法正常工作(说得温和)。
当然,我应该提到堆栈增长的方向仅在非常有限的场景中有用。 绝大多数代码都不应该关心它。 如果您对不同的体系结构以及它们如何处理堆栈感兴趣,请参阅此答案 。
您无法完全控制编译器选择分配局部变量的顺序。但是,您可以合理地控制将要调用的函数以及按什么顺序控制。
声明变量将放置在堆栈上的顺序是未定义的,但在函数调用的函数中,内部函数调用的参数必然会在外部函数的后面推送到堆栈上。
编译器可以并且对堆栈帧中的变量进行重新排序:
#include int main () { char c1; int a; char c2; int b; printf("%p %p %p %pn", &c1, &a, &c2, &b); return 0; }
打印
0x7ffff62acc1f 0x7ffff62acc18 0x7ffff62acc1e 0x7ffff62acc14
这里(在64位Linux上使用gcc 4.4.3)。 c2已移至c1旁边。
问题是当你这样做时:
void test(void) { int a; int b; if (&a < &b) ...
您得到的结果与堆栈增长方向无关。 您知道堆栈增长方式的唯一方法是创建新框架 。 编译器可以自由地在其认为合适的位置放置b
或b
以下的b
。 不同的编译器可能给出不同的结果。
但是,如果调用另一个函数,该函数的局部变量必须位于新的堆栈帧中,即从调用者变量的增长方向。
以上就是c/c++开发分享为什么函数调用而不是变量地址用于检测堆栈增长方向?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/545908.html