假设我有一个函数声明并初始化两个局部变量——默认情况下它们具有存储持续时间auto
。然后,该函数调用第二个函数,并将这两个局部变量的地址传递给该函数。第二个函数可以安全地使用这些指针吗?
一个简单的程序示例,用于补充该描述:
#include <stdio.h>
int adder(int *a, int *b)
{
return *a + *b;
}
int main()
{
auto int a = 5; // `auto' is redundant; included for clarity
auto int b = 3;
// adder() gets the addresses of two auto variables! is this an issue?
int result = adder(&a, &b);
printf("5 + 3 = %d\n", result);
return 0;
}
该程序按预期工作,打印5 + 3 = 8
.
通常,当我对 C 有疑问时,我会转向标准,这也不例外。具体来说,我检查了ISO/IEC 9899 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf,§6.2.4。它在那里部分说:
4
一个对象,其标识符声明时没有链接且没有
存储类别说明符static
has 自动存储时长.
5
对于这样一个不具有变长数组类型的对象,
它的生命周期从进入它所在的块开始延伸
关联直到该块的执行以任何方式结束。 (输入一个
封闭的块或调用函数会暂停,但不会结束,
执行当前块。)如果递归地进入块,
每次都会创建该对象的一个新实例。初始值
对象的性质是不确定的。如果指定了初始化
对象,每次到达声明时都会执行
块的执行;否则,该值将变得不确定
每次达成声明时。
读了这篇文章,我得出以下几点结论:
变量a
and b
有保存期限auto
,我已经明确使用auto
关键词。
呼叫adder()
函数对应于上面部分引用中第 5 条中的括号。也就是说,输入adder()
函数“暂停但不结束”当前块的执行(即main()
).
自从main()
块不是“以任何方式结束[ed]”,存储a
and b
是有保证的。因此,使用地址访问它们&a
and &b
,甚至在内部adder()
,应该是安全的。
那么我的问题是:我的说法正确吗?或者我只是“幸运”,并且访问了偶然未被覆盖的内存位置?
附:我无法通过 Google 或 SO 的搜索找到这个问题的确切答案。如果可以的话,请将其标记为重复项,我将删除它。
是的,它是安全的,基本上你的假设是正确的。自动对象的生命周期是从声明它的块中的条目开始直到块终止。
(C99,6.2.4p5)“对于这样的对象[...],其生命周期从进入与其关联的块开始延伸,直到该块的执行以任何方式结束。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)