简体   繁体   English

为什么这个函数返回垃圾值

[英]why does this function return garbage value

I was writing a program and facing this problem that the following function used to return garbage values: 我正在编写一个程序,并且遇到了以下函数用于返回垃圾值的问题:

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

When I modified it to this, it worked fine: 当我对此进行修改时,它工作正常:

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

What was wrong with the first version? 第一个版本出了什么问题?

The first version returns a reference to a local variable x whose storage is limited to the function foo . 第一个版本返回对局部变量x的引用,该局部变量x的存储限于函数foo When the function exits, x can no longer be used. 该函数退出后,将无法再使用x Returning a reference to it is one instance of a dangling pointer . 返回对它的引用是一个悬空指针的实例。

In the second version, you're really only passing in and returning the same pointer value, which refers to memory which isn't limited by the lifetime of the function. 在第二个版本中,您实际上只是传递并返回相同的指针值,该指针值是指不受函数寿命限制的内存。 So even after the function exits, the returned address is still valid. 因此,即使函数退出后,返回的地址仍然有效。

Another alternative: 另一种选择:

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

For each function there will be an activation record, which will be created in stack once the execution of that function starts. 对于每个功能,都会有一个激活记录,一旦该功能开始执行,就会在堆栈中创建该记录。 Activation record holds all the local variables also. 激活记录还包含所有局部变量。 And this activation record will be freed once the function execution finishes. 功能执行完成后,该激活记录将被释放。

So if we return an address of a local variable means, that will be freed memory of previous function`s activation record. 因此,如果我们返回一个局部变量均值的地址,则将释放先前函数的激活记录的内存。 Dereferencing that memrory is an undefined behaviour. 取消引用内存是不确定的行为。

In the below case, function foo is returning the &x that means p will holds the address of func 's local variable x . 在以下情况下,函数foo返回了&x ,这意味着p将保存func的局部变量x的地址。 This is valid. 这是有效的。 But if function func tries to retrun p (address of x ) which is not valid. 但是,如果函数func尝试重新运行无效的px地址)。

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
}

In the below case, funciton foo is returning address of its local variable x to function func . 在以下情况下,funciton foo将其局部变量x地址返回给func So p will holds address of foo 's local variable. 因此, p将保存foo的局部变量的地址。 So deferencing p is invalid because foo functions execution has been completed and its activation record is freed. 因此,推迟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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM