![](/img/trans.png)
[英]Extra destructor in Constructor, Copy constructor, Destructor sequence in C++
[英]Copy constructor and destructor octree c++
我已经创建了一个Octree数据结构,但是还不够完善。 我为复制构造函数和析构函数而苦恼。 这是我的头文件:
class Octree
{
public:
static int lastbranch;
static bool utolsoelotti;
struct node
{
int value;
node *child[8];
};
Octree();
~Octree();
Octree(const Octree& oct);
void clear(node* node);
node* searchandset(int dec, int value);
node* search(int dec);
node* step(node *node, int k);
node* copy(node *n);
void Print(node *n)const;
void deletebranch(int branch);
node *root;
};
构造函数,析构函数,复制构造函数
Octree::Octree()
{
root = new node;
root->value = 0;
for (int i = 0; i < 8; i++)
root->child[i] = 0;
}
Octree::~Octree()
{
clear(root);
}
Octree::Octree(const Octree& oct) {
root = copy(oct.root);
}
void Octree::clear(node *node){
for (int i = 0; i < 8; i++)
if (node->child[i])
clear(node->child[i]);
delete node;
}
Octree::node*Octree::copy(node *n) {
node* n2 = new node;
if (n) {
for (int i = 0; i < 8; i++) {
n2->child[i] = copy(n->child[i]);
}
}
return n2;
}
这是我在主体中创建对象的方式:
int main() {
Octree tree;
Octree tree2(tree);
tree.searchandset(8, 2);
tree2.Print(tree2.search(8));
return 0;
}
在searchandset
函数中,我给第一棵树的8号节点提供了一个值。 之后,我要调用复制构造函数并打印第二棵树的第8个节点。 该值与我为第一棵树提供的值相同,但是当调用调用器时,我总是遇到此异常:
引发异常:读取访问冲突。 节点为0xDDDDDDDD。
据我所知,这意味着我试图删除已经删除的节点。 对象'tree2'与具有相同值和节点的'tree'是不同的对象,不是吗? 那我不明白上面的那个例外。 我是c ++的新手,我知道这是基本知识,因此,如果有人将我引向正确的方向,我将非常感激。
问题出在copy
功能上。 让我们逐步进行:
node* n2 = new node;
if (n) {
for (int i = 0; i < 8; i++)
n2->child[i] = copy(n->child[i]);
}
return n2;
对于一个空的Octree oct
,使用默认构造函数构造并复制到另一个Octree
:
node
, n2
n
是oct
的root
,因此条件为true
n2
child[i]
具有对应子项的copy
的值,因此请再次调用copy
n2
n
是nullptr
(因为这里所有的孩子nullptr
在oct
),所以不执行条件 n2
3
至6
8次 n2
n2
)分配给复制对象的root
可是等等! 您是否注意到在第6步中,即使该孩子被认为是nullptr
,也要return
一个新的指针!
这就是问题所在,因为这样,您clear
会遍历每个孩子。 没关系,对吗? 但是,然后,您尝试访问未初始化的子项(它们具有随机值,条件的结果将为true
),因此您会遇到Read access violation
,因为这不是您的内存。
那么解决方案呢? 如果n
不为nullptr
则仅为n2
分配内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.