【问题标题】:Can I return local pointer to main function? [duplicate]我可以将本地指针返回到主函数吗? [复制]
【发布时间】:2018-03-09 18:32:48
【问题描述】:

我写了一个函数 f() 来返回指向主函数的本地指针。 我知道 f() 函数的内存在执行后会被释放。但是 f() 函数可以返回指向 a[2] 数组的指针。我认为 a[2] 应该被释放,但它仍然存在。

所以我想知道我是否可以编写一个可以返回本地指针的函数,并且本地指针指向函数中的局部变量? 如果可以返回,为什么a[2]的数组在f()函数结束后不会被释放?

#include <stdio.h>

int* f()
{
  int a[2] = {1, 2};
  int* p = a;
  printf("%p\n", p);
  return p;
}

int main(void)
{
  int* p = f();
  printf("%p\n", p);
  return 0;
}

【问题讨论】:

  • C 没有自己的垃圾收集器,因此在函数退出时变量仍然保留内存,但在函数调用退出时程序无法控制这些变量并且不能保证这些变量不能被其他一些定义或变量声明覆盖。其他一些函数可能会获得与前一个函数分配的相同的堆栈。
  • @GauravPathak 注意:面向对象并不意味着它有垃圾收集器。
  • 不能返回本地指针,以后再使用。
  • @Havenard 我同意!但我猜大多数面向对象的语言都有 GC,如果我没记错的话。
  • @GauravPathak:C++ 声称(正确地)具有面向对象的特性,但没有任何 GC。

标签: c pointers


【解决方案1】:

由于您指向的数组将超出范围并不再存在,因此尝试取消引用返回的指针将导致 undefined behavior

然而,实际上内存仍然存在,如果后面的函数调用没有覆盖任何内容,它仍然会原封不动地在那里。因此,如果您尝试取消引用指针,您仍然会看到数据。但是你不应该那样做!

关于你在做什么,你实际上并没有取消引用指针,所以你没有有 UB。您所做的只是打印指针本身的值。

【讨论】:

    【解决方案2】:

    是的,您可以(不幸地)返回指针。不,这不是一个好主意。指针将指向标记为不再使用的内存,这意味着如果您尝试取消引用它,您很可能会遇到段错误。也就是说,如果你幸运的话,你会得到一个段错误 - 如果没有,你会得到一个随机值或其他一些未定义的行为。

    【讨论】:

    • 内存不是freed,但包含它的调用帧已从调用堆栈中弹出。
    • 不是free()d,而是被释放了,意思是一般意义上的“标记为免费使用”。
    • 我会说“释放”或“摧毁”或“消失”而不是“释放”
    • 问题是这些词中的大多数也已经被占用以获得更精确的含义:-) 我试过“标记为不再使用”,希望有效。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    • 2017-02-01
    相关资源
    最近更新 更多