(我认为这个问题在技术上与Can a local variable's memory be accessed outside its scope?不同,因为它是C而不是C ++。)
我知道在C中你可以将一个局部变量放在一个块中,它将作用于该块:
#include <stdio.h>
int main() {
{
int x = 5;
printf("x = '%d'\n", x);
}
// can't see x anymore
}
我的问题是,在函数结束之前使用该内存仍然是安全的吗?从设计/编码实践角度来看它是否是WISE是一个单独的问题,但是它是未定义的行为还是我可以指望那些内存保持不变?例如:
#include <stdio.h>
int main() {
int *ptr;
{
int x = 5;
printf("x = '%d'\n", x);
// hold on to a ptr while we still know the address
ptr = &x;
}
// can't see x anymore, but is this safe?
printf("still have a ptr! '%d'\n", *ptr);
}
谢谢!
答案 0 :(得分:2)
在函数结束之前使用该内存仍然是安全的吗?
不,不是。一旦变量超出范围,对它曾经占用的内存的任何引用都是未定义的行为。
这是一个简短的演示,当编译器重用块中分配的内存时会发生UB:
int *ptr1, *ptr2;
{
int x[8];
scanf("%d", x);
printf("You entered x=%d\n", x[0]);
ptr1 = x;
}
{
int y[8];
scanf("%d", y);
printf("You entered y=%d\n", y[0]);
ptr2 = y;
}
printf("Now x=%d\n", *ptr1); // <<== Undefined behavior!!!
printf("Now y=%d\n", *ptr2); // <<== Undefined behavior!!!
我创建了一个数组,因为用于演示的编译器选择不重用单个变量和较小数组的内存。但是,一旦超过某个阈值,就会重复使用内存。
此演示展示了如何int x[8]
重复使用int y[8]
的地址。
答案 1 :(得分:2)
C99,6.2.4 p2标准说:
如果某个对象在其生命周期之外被引用, 行为未定义。指针的值变为 当它指向的对象到达其末尾时不确定 寿命。
答案 2 :(得分:1)
一旦你在街区之外,你无法安全地查看指针指向的内容,正如你所怀疑的那样。
当然,用于X值的“内存位置”依然存在,因此某些很可能存在。但访问它并不能保证安全的结果;你可能会看到垃圾,在极端情况下它甚至可能会使程序崩溃。 (并且在一段时间内,您可能会发现X的原始值仍然存在!这是一个红色的鲱鱼;它不能使用它。)
答案 3 :(得分:0)
它未定义的行为。它可能适用于某些体系结构或操作系统,但不要指望它。它可能起作用的一个例子是Linux,启用了red zone。