【问题标题】:malloc retain value between function callmalloc 在函数调用之间保留值
【发布时间】:2016-08-12 05:17:40
【问题描述】:
void func(){ 
     int *ptr;
     printf("\n *** %d\n",*ptr);
     ptr=malloc(sizeof(int));
     *ptr=111;
     printf("\n ##### %d\n",*ptr);
}

int main()
{
    func();
    func();
    return(0);
}

GCC 中的输出

 *** -1991643855   // Junk value for the first call
 ##### 111         // After allocating and assigning value
 *** 111           // second call pointer the value which 111
 ##### 111         // second call after assigning

我对 func() 中 malloc 的行为感到困惑。在第一次调用之后,局部变量指针 ptr 在堆栈帧中被清除。在第二次调用期间,在新的堆栈帧中再次创建 ptr。所以ptr没有指向任何地方。那么怎么在第二次调用的时候打印出来的时候,却指向了111的内存位置。可能很傻。我用谷歌搜索了很多,但没有找到明确的答案。

【问题讨论】:

  • 可能是新创建的帧在同一个内存上。也就是说,这实际上是在引发未定义的行为,因此无法确定。
  • 您可能会发现this answer 很有用。
  • 在对func() 的两次调用之间添加printf("Just for kicks - %d\n", 37); 并查看行为如何变化。另请注意,输出行应以换行符结尾;开头的换行符是可选的,只有在需要双倍行距时才需要。在您输出换行符之前,您的输出可能不会出现 - 有时这可能会产生误导。
  • 这显然是 C 代码,因为 malloc 需要在 C++ 中进行强制转换。

标签: c pointers


【解决方案1】:

ptr 在分配某个值之前将具有不确定的值。并且取消引用具有不确定值的指针将调用undefined behavior,这可能会导致任何结果——包括在您第一次调用func 时看到的打印垃圾值,在第二次调用func 时看到打印111,甚至让你的程序崩溃。

作为附注,在func 的末尾添加free(ptr);,以便您的程序释放使用malloc 动态分配的内存。

【讨论】:

    【解决方案2】:

    这实际上是在引发未定义的行为,因此无法确定。访问未初始化的变量是未定义的行为。

    也就是说,创建的新框架可能在同一内存上。

    【讨论】:

    • 最好提一下 what 实际上会调用未定义的行为以及 why
    【解决方案3】:

    在初始化它之前声明一个指针并取消引用它是未定义的行为——它可以包含任何东西。我相信您的指针第二次打印相同值的原因是因为func() 的堆栈帧在第一次调用后被弹出。然后您再次调用它,导致将相同的堆栈帧推送到第一个堆栈帧所在的位置。它提供的用于存储指针的内存恰好与在上一次调用中分配给指针的内存相同。

    注意:您应该在退出函数之前释放分配的内存,否则您会出现内存泄漏。

    【讨论】:

      猜你喜欢
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 2016-06-15
      • 2016-12-06
      • 2020-08-21
      • 2018-07-18
      • 1970-01-01
      • 2013-11-06
      相关资源
      最近更新 更多