我不确定此问题是否曾被提出过(通过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 ++中,当我在函数内声明局部变量时,范围仅存在于函数内部。现在当我从函数返回指针时它是如何工作的?我能够理解逻辑并得到结果(幸运的是)但我无法完全理解这里的工作。
有人可以清楚我的怀疑吗?
答案 0 :(得分: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
中的所述内存的地址通过将x
返回值分配给fn
转移到x
。
答案 1 :(得分:2)
不确定是否有其他人以这种方式解释,但指针本身只不过是一个数字,如... 0x12345678。该数字反过来解决了计算机内存中包含您要查找的实际值的位置,即链表节点。
因此,当您返回该地址时,原始变量被销毁是可以的。就像将街道地址复制到另一张纸上一样,然后扔掉原始纸张。你所在地址的房子仍在那里。
答案 2 :(得分:1)
离开函数时,指针 object tempList不再存在。但那没关系;您将返回(副本)存储在对象中的值,而不是对象本身。这就像
int n = 42;
return n;
(返回局部变量的地址会让你遇到麻烦。)
答案 3 :(得分:0)
我假设你的链表节点是在免费商店分配的(即用new
)。
当您使用new
创建对象时,它会在免费商店中创建并存在,直到您在其上调用delete
为止。您可以根据需要创建指向该位置的指针,并且它可以独立于它可能已经进行的任何函数调用而存在。因此,在此函数中,您只是将值指针返回到免费存储上的该位置。指针只是一个数字,它是对象的地址,就像按值返回int
一样。
tl; dr:你显然知道你可以按值返回本地对象,因为复制了。在此函数中,它返回指针的副本,该副本指向空闲存储上的一个位置,该位置仅在使用指向该内存位置的指针调用delete
时销毁。
另外请注意,您可能不应该返回指向列表新头部的指针,而是通过引用获取指向列表头部的指针并通过该列表更改列表,因此如果有人忘记分配旧头部指向recurrsiveReverseList
返回的指针,事情并没有弄乱。
答案 4 :(得分:0)
tempList 变量的使用范围在方法中作为其本地限制,但它包含一个返回的内存地址。 调用它的代码将接收此内存地址,而不是变量tempList。