假设我有一个函数声明并初始化两个局部变量 – 默认情况下,存储持续时间为auto
。 然后,该函数调用第二个函数,它传递这两个局部变量的地址。 第二个function可以安全地使用这些指针吗?
一个简单的程序化示例,以补充该描述:
#include 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 = %dn", result); return 0; }
此程序按预期工作,打印5 + 3 = 8
。
通常,当我对C有疑问时,我会转向标准,这也不例外。 具体来说,我检查了ISO / IEC 9899 ,§6.2.4。 它在那里说:
4声明标识符没有链接且没有存储类说明符
static
具有自动存储持续时间 。5对于没有可变长度数组类型的对象,其生命周期从entry进入与其关联的块,直到该块的执行以任何方式结束。 (输入一个封闭的块或调用一个函数会暂停,但不会结束当前块的执行。)如果以递归方式输入该块,则每次都会创建一个新的对象实例。 对象的初始值是不确定的。 如果为对象指定了初始化,则每次在执行块时达到声明时都会执行初始化; 否则,每次达到声明时,该值将变为不确定。
读这篇文章,我提出以下几点:
那么我的问题是:我对此是否正确? 或者我只是“幸运”,并访问记忆位置,偶然,没有被覆盖?
PS我无法通过Google或SO的搜索找到这个问题的确切答案。 如果可以,请将此标记为重复,我将删除它。
是的,它是安全的,基本上你的假设是正确的。 自动对象的生命周期来自声明它的块中的条目,直到块终止。
(C99,6.2.4p5)“对于这样的对象,它的生命周期从进入与其相关联的块延伸,直到该块的执行以任何方式结束。
您的推理对于您的特定函数调用链是正确的,并且您已阅读并引用了标准的相关部分。 这是对局部变量指针的完美有效使用。
如果函数将指针值存储在生命周期长于其自身调用的结构中,则必须谨慎。 考虑两个函数, foo()
和bar()
:
int *g_ptr; void bar (int *p) { g_ptr = p; } void foo () { int x = 10; bar(&x); } int main () { foo (); /* ...do something with g_ptr? */ return 0; }
在这种情况下,变量x
s的生命周期以foo()
返回结束。 但是,指向x
的指针已经通过bar()
存储在g_ptr
。 在这种情况下, foo()
将指向其局部变量x
的指针传递给bar()
。
这意味着为了知道将指向局部变量的指针传递给函数是否有效,你必须知道该函数将对它做什么。
这些变量在堆栈中分配。 只要您不从声明它们的函数返回,它们仍然有效。
由于我还没有被允许发表评论,我宁愿写另一个答案作为上述jxh答案的修正案:
有关类似的问题,请在此处查看我的精心解答 。 这包含一个真实世界的例子,即使它遵循所有的c语言规则,被调用函数中的别名使你的代码中断。
即使它在C语言中是合法的,我认为在函数调用中将指针传递给自动变量也是有害的。 你永远不会知道(并且通常你不想知道)被调用的函数对传递的值的作用。 当被调用函数建立别名时,会遇到大麻烦。
需要了解更多c/c++开发分享安全地将指向自动变量的指针传递给函数?,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享安全地将指向自动变量的指针传递给函数?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979791.html