当使 unsigned int 指针指向它自己的地址时,您可以将返回地址增加 10 以在函数返回后跳过一行。示例:
#include <stdio.h>
void f()
{
unsigned int *array = (unsigned int *) &array;
array[4] = array[4] + 10;
}
void main()
{
f();
printf("I am skipped\n");
}
为什么增量必须是 10?这个数字有什么意义以及幕后发生的事情。
通过 C v7.5.0-gcc 在 main [✘!?] 上编程 ❯ gcc stack_overflow_question.c -o 问题; ./问题
(无输出)因此,该行被跳过。
该代码具有未定义的行为:指针被初始化为指向自身,并且代码从该地址访问索引 4 处的内存,即:超出内存中指针地址的 16 个字节。
在目标架构上,运气好的话,这个地址指的是函数
f()
的堆栈中的返回地址,并且代码修补这个地址以进一步指向10个字节,这当然是非常危险的,但似乎是可执行代码调用函数后printf
。
正如您所观察到的,效果是
printf
没有被调用并且程序正常退出。
请注意,此行为非常特定于所使用的编译器、体系结构、操作系统和配置,并且绝不保证。
未定义的行为意味着任何事情都可能发生,包括没有任何可见或可怕的副作用。