2016-05-16 153 views
0

我已经创建了一个八叉树数据结构,但它并不完美。我正在努力与复制构造函数和析构函数。 这里是我的头文件:复制构造函数和析构函数八叉树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; 
}; 

构造函数,析构函数,复制contrsuctor

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++的新手,我知道它是基本的东西,所以如果有人会指引我进入正确的方向,我将非常感激。

+1

不应该'copy'返回'n2'? – Rakete1111

+0

你说得对。但问题仍然存在。 –

+0

如果你复制一个有空子节点的节点,那么在副本中,空子节点在原来的对应槽中的节点内容是什么? – HostileFork

回答

1

问题出在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

  1. 创建一个新的noden2
  2. n是因此true
  3. child[i]n2有相应子的copy的价值,因此再次呼吁copy
  4. 新节点n2创建
  5. nnullptr(因为其中oct所有nullptr的孩子),所以不执行条件
  6. 返回n2
  7. 重复步骤36 8倍
  8. 返回根n2
  9. 分配新指针(n2)来复制的对象

但是,root等待!您是否注意到在步骤6中,您是return一个新的指针,即使该孩子应该是nullptr

这就是问题所在,因为在clear中,你会遍历每个孩子。这还行,对吧?但是,您尝试访问未初始化的子项(它们具有随机值,条件将评估为true),因此您获得Read access violation,因为这不是你的记忆。

那么解决方案?如果n不是nullptr,则仅分配内存n2

+0

我上面编辑了我的代码。这就是你想要的吗?如果我这样做没有“读取访问冲突”,但复制树的值与原始树的值不同。 –

+0

@ T.dog是的,因为您没有复制该值 – Rakete1111

+0

@ T.dog不要更新问题中的原始代码。 – 0x499602D2