制作一个非常简单的链表,我发现自己对可能是一个非常简单的作用域概念感到困惑。第一部作品符合预期。似乎在第二个makeNode函数中,节点“ n”在终止时超出范围。我很困惑为什么会这样。
我很确定分配的内存仍然存在,并且这两种方法都有指向该内存的指针。那为什么不工作呢?
程序具有两个make节点功能
#include <iostream>
using namespace std;
struct Node
{
int value;
Node* next;
Node() : next(NULL){}
};
Node* makeNode1(int value)
{
Node* n = new Node;
n->value = value;
return n;
}
void makeNode2(int value, Node* mountPt)
{
Node* n = new Node;
n->value = value;
mountPt = n;
}
void destroyNode(Node* mountPt)
{
if(mountPt->next != NULL)
{
destroyNode(mountPt->next);
delete mountPt;
}
}
int main() {
Node* origin = NULL;
// This works
origin = makeNode1(4);
// causes a runtime error when dereferenced
makeNode2(4, origin);
return 0;
}
答案 0 :(得分:2)
对于makeNode2
,指针参数mountPt
本身是按值传递的,那么在函数内部mountPt = n;
指针本身的任何修改都与原始参数{ {1}}。
您可以将其更改为通过引用,即
origin
答案 1 :(得分:1)
在第一个实例中,您将创建一个新的内存部分,并带有指向该内存部分的指针(这只是一个地址),然后返回该地址。第二个示例传入一个指向内存中地址的指针,然后在函数范围内重新分配该地址(即更改该值)。但是,一旦函数退出,该指针的值(它所指向的地址)将返回到其先前的调用,因为该指针已在堆栈上具有一个值。区别在于,在第一次调用中,您更改了存储在最终从函数传递出去的地址中的值,而在第二次调用中,您更改了指针所指向的地址,但是指针又回到了指向旧地址的位置一旦将范围更改回主体。
答案 2 :(得分:0)
更改以下功能:
void makeNode2(int value, Node* mountPt)
{
Node* n = new Node;
n->value = value;
if(mountPt) delete mountPt;
mountPt = n;
}
如果已经分配了mountPt,它将被释放,然后origin
可以指向分配n
答案 3 :(得分:0)
XY解决方案:通过扩展Node构造函数来消除对makeNode
函数的需求
struct Node
{
int value;
Node* next;
Node(int val = 0) :value(val), next(NULL){}
};
用法
Node * origin = new Node(4);
答案 4 :(得分:0)
尽管以上所有内容(包括接受的答案)都是相关的,但没有一个直接指出实际的逻辑缺陷。您需要$reservationBtn.unbind('click');
来代替mountPt = n;
。