一旦它超出范围,C会重用本地块var的内存吗?

时间:2016-09-16 12:47:51

标签: c memory memory-management scope

(我认为这个问题在技术上与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);
}

谢谢!

4 个答案:

答案 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!!!

我创建了一个数组,因为用于演示的编译器选择不重用单个变量和较小数组的内存。但是,一旦超过某个阈值,就会重复使用内存。

Demo.

此演示展示了如何int x[8]重复使用int y[8]的地址。

答案 1 :(得分:2)

C99,6.2.4 p2标准说:

  

如果某个对象在其生命周期之外被引用,   行为未定义。指针的值变为   当它指向的对象到达其末尾时不确定   寿命。

答案 2 :(得分:1)

一旦你在街区之外,你无法安全地查看指针指向的内容,正如你所怀疑的那样。

当然,用于X值的“内存位置”依然存在,因此某些很可能存在。但访问它并不能保证安全的结果;你可能会看到垃圾,在极端情况下它甚至可能会使程序崩溃。 (并且在一段时间内,您可能会发现X的原始值仍然存在!这是一个红色的鲱鱼;它不能使用它。)

答案 3 :(得分:0)

它未定义的行为。它可能适用于某些体系结构或操作系统,但不要指望它。它可能起作用的一个例子是Linux,启用了red zone