1

我不确定之前是否有人问过这个问题(通过 SOF 搜索并找不到答案)

我写了一个LinkedList类和一个反转它的函数。函数如下,

    struct LinkedList::element* LinkedList::recurrsiveReverseList(element* head){
     element* tempList;
     if(head->next == NULL){
        return head;
     }else{
        tempList = recurrsiveReverseList(head->next);
        head->next->next = head;
        head->next = NULL;
        return tempList;        
    }
   }

在这里,我声明了一个局部指针变量并对它进行了一些更改并将其返回给调用者。在 C++ 中,当我在函数内声明局部变量时,范围仅存在于函数内。现在,当我从函数返回指针时,它是如何工作的?我能够理解逻辑并得到结果(幸运的是),但我无法完全理解这里的工作。

有人可以解决我的疑问吗?

4

5 回答 5

2

tempList当您退出函数时,范围终止,但tempList它是一个指向内存块的指针,其范围不会那里终止,因为它无疑是由new. 以这种方式分配的内存在您使用delete它之前一直有效,无论您进入或退出多少功能。

通过将指针传递回调用者,它将所述指针保留在其他地方,您可以在其中使用它。

一个简单的例子:

static char *fn (void) {
    char *rv = new char[42];
    return rv;
}

int main (void) {
    char *x = fn();
    delete [] x;
    return 0;
}

在上面的代码中,作用域rv仅限于fn声明后的函数。

的范围x仅限于main声明后的函数。

但是 分配的内存new在 内部存在fn并在返回 后继续main存在。最初存储在 中的所述存储器的地址通过将返回值分配给 来rv传送。xfnx

于 2011-08-23T03:39:51.003 回答
2

不确定其他人是否这样解释,但指针本身只不过是一个数字,比如...... 0x12345678。该数字又指向计算机内存中包含您要查找的实际值的位置,即链表节点。

因此,当您返回该地址时,原始变量被破坏是可以的。就像将街道地址复制到另一张纸上,然后扔掉原始纸。你所拥有的地址的房子仍然在那里。

于 2011-08-23T03:47:32.350 回答
1

当您离开该函数时,指针对象tempList 将不复存在。但这没关系;您正在返回(副本)存储在对象中的值,而不是对象本身。就像

int n = 42;
return n;

(返回局部变量的地址会给你带来麻烦。)

于 2011-08-23T03:41:09.297 回答
0

我假设您的链表节点是在免费存储上分配的(即使用new)。

当您使用 来创建对象时new,它会在免费存储中创建并一直存在,直到您调用delete它为止。您可以根据需要创建指向该位置的任意数量的指针,并且它的存在独立于可能已在其中进行的任何函数调用。因此,在此函数中,您只是按值返回指向自由存储上该位置的指针。指针只是一个数字,它是对象的地址,就像int按值返回一样。

tl; dr:您显然知道可以按值返回本地对象,因为已制作副本。在这个函数中,它返回一个指针的副本,该指针指向空闲存储上的一个位置,该位置只有在delete使用指向该内存位置的指针调用时才会被销毁。

另请注意,您可能不应该返回指向列表新头的指针,而是通过引用获取指向列表头的指针并通过它更改列表,因此如果有人忘记将旧头指针分配给一个被退回recurrsiveReverseList,事情没有搞砸。

于 2011-08-23T03:39:18.943 回答
0

tempList变量的使用范围仅限于方法中的本地变量,但它包含一个返回的内存地址。调用它的代码将接收这个内存地址,而不是变量 tempList。

于 2011-08-23T03:40:14.443 回答