【问题标题】:Returning pointer in function在函数中返回指针
【发布时间】:2016-06-27 13:33:36
【问题描述】:

为什么我在第二个 printf 语句中没有得到 20 作为输出?

int main() {
    int *p;
    int * fun();
    p = fun();
    printf("%d\n", p);
    printf("%d", *p);

    return 0;
}

int * fun() {
    int i = 20;
    return (&i);
}

【问题讨论】:

标签: c pointers scope


【解决方案1】:

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; }

那么这将按您的预期工作,因为static 对象存在于程序的整个生命周期中。但是,对于这个特定问题,这不是一个好的解决方案。

【讨论】:

    【解决方案2】:

    您不能在堆栈上分配整数(在您的情况下在函数范围内)并在范围外使用它。

    原因是为函数分配的内存(= 堆栈)在函数结束后被认为是空闲的。

    挖一点北斗 - 你的进程有操作系统提供的虚拟内存。此内存由进程管理,您调用的每个函数都会获得由进程分配给它的 disposable 内存(这是堆栈)。一旦函数返回,该内存将被应用程序回收用于其他用途

    所以在您的示例中:
    call int *fun() alloca 都存在于函数堆栈中
    return &1

    这就是尝试访问该内存(在您的情况下为整数 i)时在函数外部使用该内存是非法的原因(感谢 @Eugene)

    【讨论】:

      【解决方案3】:

      函数中的变量i是它的局部变量,一般退出函数后会被销毁。 所以返回的指针是无效的,程序有未定义的行为。

      您可以通过以下方式更改功能

      int * fun( void )
      {
          static int i = 20;
          return &i;
      }
      

      在这种情况下,变量i 将具有静态存储持续时间,并且在退出函数后将处于活动状态。

      考虑到在 C 中的以下声明

      int * fun();
      

      int * fun( void );
      

      不等价。

      第一个声明意味着对函数参数一无所知。 你应该像这样声明你的函数

      int * fun( void );
      

      不带参数的 main 也应该像 C 一样声明

      int main( void )
      

      要输出指针,您应该使用格式说明符 %p 而不是 %d

      printf("%p\n",p);
              ^^^
      

      【讨论】:

      • 通过对不熟悉范围概念的人使用不太简单的静态变量概念来解决所述问题并不是一个好主意。国际海事组织。
      • @EugeneSh。这你的评论也没有意义。我展示了如何使指针有效,仅此而已。
      猜你喜欢
      • 2013-04-10
      • 1970-01-01
      • 2018-08-19
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      相关资源
      最近更新 更多