在函数中返回指针

时间:2016-06-27 13:33:36

标签: c pointers scope

为什么我在第二个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);
}

3 个答案:

答案 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);
        ^^^