c - 即使在函数返回后,在函数内部声明的非静态指针变量似乎也被保留了
问题描述
这个问题不是这个的完全重复。这里最流行的答案是说不能保证内存位置会被保留,但它却意外地保留了。从我得到这段代码的地方,它清楚地表明字符串变量将被保留。
考虑以下代码:
#include<stdio.h>
char *getString()
{
char *str = "abc";
return str;
}
int main()
{
printf("%s", getString());
getchar();
return 0;
}
此代码编译并运行没有任何错误。指针char* str
未定义为静态变量。然而,即使在函数返回后,变量似乎也被保留了下来。
请解释这种行为。
我不明白为什么这个问题得到了反对票,即使它还没有回答或标记为重复。
解决方案
char *getString() ... char *str = "abc";
你正在制造一些混乱。getString() 在堆栈中创建一个变量,并使其指向一个文字字符串。那个字面可以在任何地方,并且永远在那里;根据编译器的不同,它可以在启动时初始化的 RAM 中,也可以在只读存储器中。好的:如果它在 RAM 中,也许您甚至可以修改它,但不能以正常(合法)的方式 - 我们应该忽略这一点,并将其视为不可变数据。
上面的点是点。字符串“被保留”是真的。但是保留自动变量是不正确的——它可能会发生,但你不应该依赖它,如果你这样做是一个错误。根据定义,当函数返回时,自动变量会被销毁,并确保它发生。
也就是说,我不明白你怎么能说变量被保留了。C 中没有查看局部变量的机制(在当前范围之外);你可以用调试器来做,特别是当活动框架是 getString(); 也许某些调试器可以让您查看不应该查看的位置,但这是另一回事。
评论后编辑
许多编译器在堆栈中创建自动(局部)变量。当函数返回时,堆栈上的数据保持不变,因为清除/销毁堆栈只需将堆栈指针移动到其他位置即可。所以“变量似乎被保留”的肯定是正确的。似乎是因为实际上变量仍然存在。似乎是因为没有合法的方式使用它。但是即使在这种情况下,变量仍然存在但被隐藏,编译器可以决定使用那个房间做其他事情,或者一个中断可以到达并使用同一个房间。换句话说,当 auto 变量在作用域内时,它保证被“保留”,但是当它超出作用域时,它必须被认为是消失了。
在某些情况下,可以编写引用超出范围的变量的代码:这些是编译器应该(有时可以)检测到的错误。
我说过自动变量通常会进入堆栈。这并不总是正确的,它取决于架构和编译器,但其余的都是正确的,并且由语言规则决定。
推荐阅读
- autocomplete - 当用户单击任何站点时隐藏 ul
- c# - IO 异常 (XML) - 进程无法访问该文件,因为它被另一个进程使用
- reactjs - 如何设置 react-dom/server renderToString 传递给 graphql 服务器的标头?
- javascript - 如何将选定的选项用作函数中的变量?
- python - 在 Python 中重新排列和求解方程
- c# - Azure 函数中的 AppDomain
- matlab - 在 Matlab 中对 N 维数据进行离散化/分箱以实现可视化
- javascript - 为什么我的 [Op.or] 只能部分工作?
- r - runjs 在 flexdashboard 中更改 observeEvent 的位置?
- java - Spring Bean - 带参数的构造函数