C语言能否通过函数地址偏移访问其内部局部变量的取值?
结论
这种实现方式完全不可行,属于C语言标准明确的未定义行为,没有任何可靠性、可移植性可言。
为什么不能这么做?
- 首先,C标准没有定义任何对函数指针执行算术运算的行为:
func是函数指针,你直接执行func + 4本身就是非法操作,不同编译器、不同CPU架构、不同编译参数下,这个偏移的含义完全不同,甚至部分架构会直接禁止对函数指针执行整数加减操作。 - 你要访问的
i是func内部的自动局部变量,它的内存分配在栈上:只有func被调用时才会临时分配栈帧、给i赋值4,func执行结束后栈帧立即被回收,这块内存的内容会被后续的其他函数调用、栈操作随意覆盖,你在main里访问的时候,这块内存早就不是原来的i的值了。 - 就算你在
func调用之后立即读取栈,编译器也可能直接把i优化掉:因为i在func内部没有被任何操作使用,开O1及以上优化等级时,int i = 4;这行代码会被直接删除,你根本找不到这个值的存储位置。 - 你当前输出的
83641799根本不是你想要的4,转成十六进制后它就是func函数对应的机器码的字节内容,和栈上的局部变量没有任何关系。
如果你想在函数外部访问func内部的i,可以用以下合法方式:
- 把
i声明为静态局部变量:
int* func() { static int i = 4; return &i; } int main() { int *k = func(); printf("%d\n", *k); return 0; }
- 动态分配内存存储
i,返回指针后记得手动释放:
int* func() { int *p = malloc(sizeof(int)); *p = 4; return p; } int main() { int *k = func(); printf("%d\n", *k); free(k); return 0; }
- 也可以在外部定义变量,把指针传入
func修改值。
内容的提问来源于stack exchange,提问作者Milan
相关产品推荐
相关产品推荐

