为啥这个函数返回垃圾值
Posted
技术标签:
【中文标题】为啥这个函数返回垃圾值【英文标题】:why does this function return garbage value为什么这个函数返回垃圾值 【发布时间】:2012-08-20 17:52:57 【问题描述】:我正在编写一个程序,并面临以下函数用于返回垃圾值的问题:
int* foo(int temp)
int x = temp;
return &x;
当我修改它时,它工作正常:
int* foo(int *temp)
int *x = temp;
return x
第一个版本有什么问题?
【问题讨论】:
我不确定是否有 C 标记,但这个故事很有趣,而且是同样的问题:***.com/questions/6441218/… 【参考方案1】:第一个版本返回对局部变量x
的引用,该变量的存储仅限于函数foo
。当函数退出时,x
就不能再使用了。返回对它的引用是悬空指针的一个实例。
在第二个版本中,您实际上只是传入和返回相同的指针值,它指的是不受函数生命周期限制的内存。所以即使函数退出后,返回的地址仍然有效。
另一种选择:
int *foo(int temp)
int *x = malloc(sizeof(int));
*x = temp;
return x;
【讨论】:
我不确定你的意思。您的意思是使用作为对象成员的变量吗? 如果你指的是结构或C++对象,这取决于它们是分配在堆栈上还是堆上。 当您打算返回一个指向整数的指针 (int*
) 时,您要么需要在调用函数之前已分配成员,要么使用 malloc()
分配新内存。您应该永远不要将指向局部变量的指针作为函数输出返回。
@pb2q 范围和存储持续时间是不同的东西,变量可以超出范围但它的存储仍然存在。
@ouah 我不相信我混淆了答案中的差异。如果我有,建议重新措辞?【参考方案2】:
对于每个函数,都会有一个激活记录,一旦该函数开始执行,就会在堆栈中创建该记录。激活记录也包含所有的局部变量。并且一旦函数执行完成,这个激活记录就会被释放。
因此,如果我们返回一个局部变量的地址,则意味着将释放先前函数的激活记录的内存。取消引用该内存是一种未定义的行为。
在下面的例子中,函数foo
返回&x
,这意味着p
将保存func
的局部变量x
的地址。这是有效的。但是如果函数func
尝试返回无效的p
(地址x
)。
int* func
int x;
int *p;
...
p = foo(&x);
//using p is valid here
...
return p; //This is invalid
int* foo(int *temp)
int *x = temp;
return x //This is valid
在以下情况下,函数foo
将其局部变量x
的地址返回给函数func
。所以p
将保存foo
的局部变量的地址。所以推迟p
是无效的,因为foo
函数执行已经完成并且它的激活记录被释放了。
int* func
int x;
int *p;
...
p = foo(x);
//using p is invalid here
...
return p; //This is invalid
int* foo(int temp)
int x = temp;
return &x; //This is also invalid
【讨论】:
以上是关于为啥这个函数返回垃圾值的主要内容,如果未能解决你的问题,请参考以下文章