0

我正在编写一个程序并面临以下函数用于返回垃圾值的问题:

int* foo(int temp){
   int x = temp;
   return &x;
}

当我将其修改为此时,它工作正常:

int* foo(int *temp){
    int *x = temp;
    return x
}

第一个版本有什么问题?

4

2 回答 2

7

第一个版本返回对局部变量的引用,该变量x的存储仅限于函数foo。当函数退出时,x就不能再使用了。返回对它的引用是悬空指针的一个实例。

在第二个版本中,您实际上只是传入并返回相同的指针值,它指的是不受函数生命周期限制的内存。所以即使函数退出后,返回的地址仍然有效。

另一种选择:

int *foo(int temp)
{
    int *x = malloc(sizeof(int));
    *x = temp;
    return x;
}
于 2012-08-20T17:54:04.900 回答
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
}

在下面的情况下,函数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
}
于 2012-08-21T02:44:57.720 回答