虽然这是一个非常普遍的问题,但这是我的具体例子,所以你可以理解我在问什么。
我有一个四叉树类的复制构造函数。所以我写了一个名为copy的递归辅助方法,所以我可以在我的复制构造函数中调用它。帮助器接受一个参数,一个节点。从构造函数调用时,根节点作为第一个参数。
所以现在在我的帮助方法中,我创建了一个新节点,称之为newNode
,每个节点都有成员变量neChild,nwChild,seChild,swChild ---- sw表示西南nw,ne,se都是基本方向,我设置每个新孩子等于source.child。然后我在每个source.child(其中4个)上递归地再次调用helper方法。这样,1个节点变为4,然后有16个子节点,依此类推。然后我返回我创建的第一个newNode
。
新返回的节点是否会附加所有其他节点?它会在树形结构中(虽然不是正式的树)吗?或者那些附加到返回指针的指针是否超出范围?
答案 0 :(得分:1)
首先,正如其他人所指出的那样,在创建QuadtreeNode
时,您会混淆QuadtreeNode*
和newNode
。我会假设它是一个指针。
其次,你没有足够好地防范NULL。
第三,如果我对这段代码的读取是正确的,那么对copy
的四次递归调用只会产生内存泄漏;每次调用都会在堆上生成一个新节点,并返回指向该新节点的指针,但您的代码不会保留该指针。因此copy
将返回一个指向新节点的指针,该节点具有指向参数节点的子节点的子指针 - 这就是全部。
答案 1 :(得分:1)
您最终会得到一个新的根节点,该节点链接到与原始树相同的子节点。因此,对任何孩子所做的任何更改都会影响两棵树,之后您可能会遇到双重问题。
这是因为,虽然您以递归方式调用copy
,但您将丢弃返回值。
此外,您说过从您的复制构造函数调用此copy
函数?你正处于一个受伤的世界,因为copy
调用了复制构造函数(在return语句中,因为你按值返回)。这是STACK OVERFLOW的一个秘诀。我想你是在正确的地方;)
答案 2 :(得分:0)
从堆分配的东西在函数返回时不会超出范围。一个局部变量指向到堆上的东西会超出范围但是,如果你从函数返回它,那么你就是保留副本。
但是,如果这些变量是自动的(在堆栈上),那么当你返回时, 将超出范围。
并且,根据您的代码,这类似于(不发布实际代码,因为OP声明它是功课,他们不想保留副本):
XTreeNode XTreeNode::copy(XTreeNode & const n) {
XTreeNode *newNode = new XTreeNode(7); // <-- Note "*", this is important.
newNode.xy=n.xy;
return newNode;
}
您选择了我给出的这两个选项的第三个: - )
因为你正在传递n
,当你退出函数时它仍然在范围内,并且无论如何都会返回一个超出范围(newNode
)的东西,所以你会还有副本。
答案 3 :(得分:0)
假设您从QuadtreeNode*
方法返回copy
,从此函数返回的指针在此函数之外将保持有效,直到您使用delete
手动释放内存。
答案 4 :(得分:0)
如果newNode
类型为QuadtreeNode*
,则访问成员变量/方法的方法是使用->
运算符。
newNode
位于堆栈上,但它所指向的内存位于堆上(在这种情况下,对象位于此处)。因此,它返回对堆上位置的引用(如果返回类型为QuadtreeNode*
)。没关系。但是,程序需要使用delete
释放从堆/免费存储中获取的资源,否则会占用内存泄漏。