我正在编写一个程序并面临以下函数用于返回垃圾值的问题:
int* foo(int temp){
int x = temp;
return &x;
}
当我将其修改为此时,它工作正常:
int* foo(int *temp){
int *x = temp;
return x
}
第一个版本有什么问题?
第一个版本返回对局部变量的引用,该变量x
的存储仅限于函数foo
。当函数退出时,x
就不能再使用了。返回对它的引用是悬空指针的一个实例。
在第二个版本中,您实际上只是传入并返回相同的指针值,它指的是不受函数生命周期限制的内存。所以即使函数退出后,返回的地址仍然有效。
另一种选择:
int *foo(int temp)
{
int *x = malloc(sizeof(int));
*x = temp;
return x;
}
对于每个函数,都会有一个激活记录,一旦该函数开始执行,它将在堆栈中创建。激活记录也包含所有的局部变量。一旦函数执行完成,该激活记录将被释放。
因此,如果我们返回一个局部变量的地址,则意味着前一个函数的激活记录将被释放内存。取消引用该内存是一种未定义的行为。
在下面的情况下,函数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
's 局部变量的地址。所以deferencingp
是无效的,因为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
}