为什么我在第二个20
语句中不将printf
作为输出?
int main() {
int *p;
int * fun();
p = fun();
printf("%d\n", p);
printf("%d", *p);
return 0;
}
int * fun() {
int i = 20;
return (&i);
}
答案 0 :(得分:3)
当:
退出时,局部变量fun
不再存在,任何指向它的指针现在都无效。显然,i
以前占用的内存单元仍然存在,但现在可供其他内容使用,并且可能会在i
返回时间之间被覆盖,并且您尝试打印fun
。
要么函数返回*p
的值:
i
或写入参数
int fun( void ) { int i; ...; return i; }
如果已声明void fun( int *i ) { ...; *i = 20; ... }
i
:
static
然后这将按预期工作,因为int *fun( void ) { static int i; i = 20; return &i; }
对象在程序的生命周期内存在。但是,对于这个特定问题,它不是一个好的解决方案。
答案 1 :(得分:0)
您不能在堆栈上分配一个整数(在您的情况下在函数范围内)并在范围之外使用它。
原因是在函数结束后,为函数(=堆栈)分配的内存被认为是空闲的。
要挖一点杓子 - 您的进程具有操作系统提供的虚拟内存。该内存由进程管理,您调用的每个函数都会获得一个由进程分配给它的一次性内存(这是堆栈)。函数返回后,该内存将被应用程序回收用于其他用途
所以在你的例子中:
call int *fun()
< - 您声明和使用的所有变量,包括此函数中的alloca
存在于函数堆栈中
return &1
< - 现在函数已经结束,为它分配的内存再次空缺
这是使用函数外部的内存是非法的(感谢@Eugene)在尝试访问该内存时的原因(在你的情况下是整数i)
答案 2 :(得分:-1)
函数中的变量i
是其局部变量,在退出函数后通常会被销毁。
因此返回的指针无效,程序具有未定义的行为。
您可以通过以下方式更改功能
int * fun( void )
{
static int i = 20;
return &i;
}
在这种情况下,变量i
将具有静态存储持续时间,并在退出函数后将处于活动状态。
在C中考虑以下声明
int * fun();
和
int * fun( void );
不等同。
第一个声明意味着对函数参数一无所知。 你应该声明你的功能
int * fun( void );
主要没有参数应该在C中声明
int main( void )
要输出指针,您应该使用格式说明符%p
而不是%d
printf("%p\n",p);
^^^