在main中调用此函数时,是否从内存中删除了局部变量

时间:2012-08-18 01:12:55

标签: c data-structures global-variables local

  

可能重复:
  Can a local variable's memory be accessed outside its scope?
  returning address of local variable

我有一个问题,首先要看代码

    #include <stdio.h>

int sum();          /* function declaration */

int main()
{
    int *p2;
    p2 = sum();         /* Calling function sum and coping its return type to pointer variable p2  */
    printf("%d",*p2);
} /*  END of main  */ `

int sum()           
{
    int a = 10;
    int *p = &a;
    return p;
} /*  END of sum */

我认为答案是10和变量a的地址,但是我的测试人员说a函数的本地是这样的a和它的 当函数返回或执行完毕后,将从内存位置删除value。我尝试了这个代码,答案是当然10和地址,我使用GNU / GCC编译器。任何人都可以说什么是对错。 提前致谢。

5 个答案:

答案 0 :(得分:3)

您的老师是完全正确的:即使您修改程序以返回int*代替int,您的程序仍然包含未定义的行为。问题是,a返回后,sum过去的内存已经成熟,可以重复使用。内存可能保持不变,你可以访问,所以你甚至可以打印10,但这种行为仍然是未定义的:它可能在一个平台上运行而在其他十个平台上崩溃。

答案 1 :(得分:2)

你可能得到了正确的结果,但那只是因为你很幸运,在返回sum()时, a 的内存被返回给系统,并且它可以被使用通过任何其他变量,因此可以更改该值。

例如:

#include <stdio.h>

int* sum();          /* function declaration */
int* sum2();          /* function declaration */

int main()
{
    int *p2;
    p2 = sum();         /* Calling function sum and coping its return type to pointer variable p2  */
    sum2();
    printf("%d",*p2);
}

int* sum()           
{
    int a = 10;
    int *p = &a;
    return p;
} /*  END of sum */

int* sum2()           
{
    int a = 100;
    int *p = &a;
    return p;
} /*  END of sum */

使用此代码,sum2()将重用 a ,从而用100覆盖内存值。

这里你只返回一个指向int的指针,假设你要返回一个对象:

TestClass* sum()           
{
    TestClass tc;
    TestClass *p = &tc;
    return p;
}

然后当你取消引用tc时,会发生奇怪的事情,因为它指向的记忆可能完全搞砸了。

答案 2 :(得分:0)

您的指针仍然指向10位于内存中的位置。但是,从Cs的角度来看,内存是未分配的,可以重用。在堆栈上放置更多项目或分配内存可能会导致该部分内存被重用。

答案 3 :(得分:0)

函数sum中的对象a具有automatic lifetime。一旦声明它的范围(函数体)由程序流(函数末尾的return语句)保留,它的生命周期就会结束。

之后,访问a所居住的内存将执行您期望的操作,召唤龙或将计算机置于火上。这在C中称为未定义的行为。然而,C标准本身没有提到deleting something from memory,因为它没有内存概念。

答案 4 :(得分:0)

逻辑发言,a退出后sum不再存在;它的寿命仅限于功能范围。 物理上说,a占用的内存仍然存在,并且仍然包含值10的位模式,但该内存现在可用于其他用途,并且可能在之前被覆盖你可以在main中使用它。您的输出可能是10,或者可能是垃圾。

尝试访问变量生命周期之外的变量值会导致未定义的行为,这意味着编译器可以随心所欲地处理这种情况。它没有必要警告你,你正在做任何虚假的事情,它不必像你期望的那样工作,它根本不需要工作。