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