【发布时间】:2014-06-10 16:14:22
【问题描述】:
我试图理解 C 中的堆栈帧,所以我编写了一个简单的 C 代码来分析堆栈帧。
首先 fun1() 返回一个局部变量的地址,该变量初始化为 10 到 ptr,这会导致警告,但没关系...如果我现在打印 *ptr 的值,它会打印 10 ,就算这样也好……
Next fun2() 返回一个甚至没有初始化的局部变量的地址,如果我现在尝试打印 *ptr 的值,无论我返回的是 a 还是 b 的地址,它都会打印 10 ...
为了了解这里实际发生的情况,我使用了 gdb。 使用 gdb,我开始逐步调试,当我到达 fun2() 中的“return &a”行时,我尝试打印 b 的地址,print &b 但它打印 无法获取不是左值的“b”地址。
我不明白当我尝试打印 a 的地址时,print &a 它打印得非常好,那么为什么不打印 b 的地址。 * 为什么 b 不是左值,而 a 是左值?
# include <stdio.h>
int * fun1() {
int a = 10;
return &a;
}
int * fun2()
{
int a;
int b;
return &a; // return &b;
}
int main ()
{
int *ptr;
ptr = fun1();
ptr = fun2();
printf ("*ptr = %d, fun2() called...\n", *ptr);
return 0;
}
【问题讨论】:
-
您正在调用未定义的行为。无法保证结果会有意义或符合您对堆栈布局的期望。标准的夸张是允许程序让demons飞出你的鼻子。
-
你很幸运,打印
*ptr打印 10;当然不能保证这样做(您正在调用未定义的行为)。但是您确实应该显示所有代码。在代码中,编译器可能将b作为未使用的变量丢弃,因此它没有位置,因此您无法获取它的地址。在代码中使用b,不知何故,您将能够打印它。请不要报告“类似”;准确,并准确报告调试器所说的内容。 -
如果您要获取有关“堆栈框架”的文档,那么这是一个与 ABI 相关的请求,与任何编程语言都没有任何关系,您应该记录自己采用/提供的 ABI你的 CPU/架构/操作系统/实现。如果您的问题是理解 C 的工作原理,那么重点是完全不同的主题。
标签: c gcc gdb memory-layout