复制构造函数和析构函数八叉树c++
Copy constructor and destructor octree c++
我创建了一个八叉树数据结构,但还不完善。我在复制构造函数和析构函数之间挣扎。
这是我的头文件:
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;
}
下面是我在 main 中创建对象的方式:
int main() {
Octree tree;
Octree tree2(tree);
tree.searchandset(8, 2);
tree2.Print(tree2.search(8));
return 0;
}
在 searchandset
函数中,我为第一棵树中的节点号 8 赋值。之后我调用复制构造函数并打印第二棵树的第 8 个节点。该值与我为第一棵树提供的值相同,但是当调用 descstructor 时,我总是遇到此异常:
抛出异常:读取访问冲突。
节点是 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
,所以条件iftrue
child[i]
of n2
的值是对应child的一个copy
,所以再调用copy
- 创建了一个新节点
n2
n
是nullptr
(因为children where all nullptr
in oct
),所以不要执行condition
- Return
n2
- 重复步骤
3
到 6
8 次
- Return根
n2
- 将新指针 (
n2
) 分配给复制的 object 的 root
但是等等!您是否注意到在第 6 步中,您正在 return
创建一个新指针,即使 child 应该是 nullptr
!
这就是问题所在,因为那样的话,在 clear
中,您将遍历每个 child。那还是可以的,对吧?但是随后,您尝试访问未初始化的 children(它们具有随机值,条件将评估为 true
),因此您得到一个 Read access violation
,因为它不是您的内存。
那么解决方案?如果 n
不是 nullptr
.
,则只为 n2
分配内存
我创建了一个八叉树数据结构,但还不完善。我在复制构造函数和析构函数之间挣扎。 这是我的头文件:
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;
}
下面是我在 main 中创建对象的方式:
int main() {
Octree tree;
Octree tree2(tree);
tree.searchandset(8, 2);
tree2.Print(tree2.search(8));
return 0;
}
在 searchandset
函数中,我为第一棵树中的节点号 8 赋值。之后我调用复制构造函数并打印第二棵树的第 8 个节点。该值与我为第一棵树提供的值相同,但是当调用 descstructor 时,我总是遇到此异常:
抛出异常:读取访问冲突。 节点是 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
,所以条件iftrue
child[i]
ofn2
的值是对应child的一个copy
,所以再调用copy
- 创建了一个新节点
n2
n
是nullptr
(因为children where allnullptr
inoct
),所以不要执行condition- Return
n2
- 重复步骤
3
到6
8 次 - Return根
n2
- 将新指针 (
n2
) 分配给复制的 object 的
root
但是等等!您是否注意到在第 6 步中,您正在 return
创建一个新指针,即使 child 应该是 nullptr
!
这就是问题所在,因为那样的话,在 clear
中,您将遍历每个 child。那还是可以的,对吧?但是随后,您尝试访问未初始化的 children(它们具有随机值,条件将评估为 true
),因此您得到一个 Read access violation
,因为它不是您的内存。
那么解决方案?如果 n
不是 nullptr
.
n2
分配内存