【发布时间】:2019-06-16 15:49:11
【问题描述】:
以下代码不包含任何循环,或goto,或递归;但它在控制台中从 1 打印到 10。
#include <stdio.h>
int n = 1;
void foo() {
int x;
printf("%d ", n);
if (++n>10) return;
*(&x+4) -= 5;
}
int main() {
foo();
return 0;
}
这个神秘的代码*(&x+4) -= 5; 导致了循环。
据我所知,x 的值被保存在堆栈内存中。可能是这样,在(&x+4)之前有函数foo的指针,而foo正在被递归调用。
再说一次,我不确定我的假设是否正确。我也不明白5 来自哪里。我试图打印和分析函数指针和变量的地址(由我的同事建议);并将它们与我对C memory layout 的了解相匹配。但我更困惑了。
如果在x 前后声明了更多变量,*(&x+4) -= 5; 会如何变化?
操作系统: Windows-7 64 位,编译器: GNU GCC,编辑器: CodeBlocks 16.01
【问题讨论】:
-
它只打印
1然后退出。 -
这取决于未定义的行为。当
x只是int x时,您不应该取消引用(&x+4)的内存。 -
@SouravGhosh 我在网上找到了代码。我知道-我不应该那样编码。我只是想知道解释。
-
依赖堆栈布局和硬件架构细节的自修改代码。如果没有提供这些细节,这个问题是没有用的。前任在我的 Fedora 29 x86_64 和 gcc 8.2.1 上,我只遇到分段错误。老实说,那里没有错误惊喜......
-
@StefanBecker 这不是“自修改代码”,它只是破坏了自己的堆栈。
标签: c++ c loops undefined-behavior