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

C 在main中调用此函数时,是否从内存中删除局部变量,c,data-structures,global-variables,local,C,Data Structures,Global Variables,Local,可能重复: 我有一个问题,首先看看代码 #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);

可能重复:

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

    #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 */
#包括
int sum();/*函数声明*/
int main()
{
int*p2;
p2=sum();/*调用函数sum并将其返回类型转换为指针变量p2*/
printf(“%d”,*p2);
}/*主管道末端*/`
整数和()
{
INTA=10;
int*p=&a;
返回p;
}/*总和结束*/
我想答案是10和变量a的地址,但我的老师说a是函数的局部变量,所以a和它的 当函数返回或完成执行时,将从内存位置删除值。我尝试了这段代码,答案当然是weel 10和地址a,我使用GNU/GCC编译器。谁能说出什么是对的,什么是错的。
提前谢谢

您的老师是绝对正确的:即使您将程序修复为返回
int*
而不是
int
,您的程序仍然包含未定义的行为。问题在于,一旦
sum
返回,用来放置
a
的内存就可以重用了。内存可能保持不变供您访问,因此您甚至可以打印10个,但此行为仍未定义:它可能在一个平台上运行,在其他十个平台上崩溃。

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

您可能会得到正确的结果,但这只是因为您很幸运,当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 */

然后,当您取消引用tc时,会发生奇怪的事情,因为它所指向的内存可能已完全拧紧。

函数sum中的对象
a
具有
自动生存期。一旦程序流(函数末尾的
return
语句)离开声明它的作用域(函数体),它的生存期就会结束

在那之后,访问
a
所在的内存将实现您的预期,召唤龙或点燃您的计算机。这在C中被称为未定义行为。然而,C标准本身并没有说明从内存中删除某个东西,因为它没有内存的概念。

从逻辑上讲,
a
一旦
sum
退出,就不再存在;它的生命周期仅限于函数的范围。从物理上讲,
a
占用的内存仍然存在,并且仍然包含值10的位模式,但是该内存现在可供其他东西使用,并且在您可以在
main
中使用之前可能会被覆盖。您的输出可能是10,也可能是垃圾


试图访问变量生存期之外的变量值会导致未定义的行为,这意味着编译器可以自由地以任何方式处理这种情况。它不必警告你正在做任何不寻常的事情,它不必按照你期望的方式工作,它根本不必工作

对不起,我没听清楚你想说什么!好啊所以她是对的,谢谢你们,若我把var a设为静态变量,那个么会发生什么呢?静态变量在第一次被访问后具有全局生存期,所以对于某些“ok”值,它应该是ok;使
a
static使函数不可重入。在这种情况下,正确的答案是返回
a
的值,而不是它的地址。给定的程序不会编译。
sum
的返回类型不应该是
int*
?请说明原因,如果您只是想验证您的老师是否正确,请在valgrind下运行您的程序(假设您在linux或cygwin环境中)。假设你的程序名为a.out,你就运行valgrind a.out。Valgrind将通知您您犯了错误。在pmr-此程序编译并运行,在一些机器上生成输出i,e 10,在我的计算机上,我在我的堂兄弟系统上运行linux,他运行windows并使用ide。
TestClass* sum()           
{
    TestClass tc;
    TestClass *p = &tc;
    return p;
}