2016-05-16 4 views
0

私はOctreeデータ構造を作成しましたが、まだ完全ではありません。私はコピーコンストラクタとデストラクタに苦労しています。 ここに私のヘッダファイルです:コンストラクタとデストラクタ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; 
}; 

コンストラクタ、デストラクタ、コピー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の値を与えます。その後、コピーコンストラクタを呼び出して2番目のツリーの8番目のノードを出力します。値は私が最初のツリーに与えた値と同じですが、デクストラクタが呼び出されたときに私はいつもこの例外があります:

例外がスローされました:読み取りアクセス違反。 ノードは0xDDDDDDDDでした。

私が知っていることは、すでに削除したノードを削除しようとしたことを意味します。オブジェクト 'tree2'は 'tree'とは別のオブジェクトで、同じ値とノードではありませんか?それから私は上記の例外を理解していません。 私はC++で新しく、基本的なことを知っています。誰かが私を正しい方向に向けるなら、私は非常に感謝します。

+1

'コピーして' n2'を返さないのですか? – Rakete1111

+0

あなたは正しいです。しかし、問題はまだ存在しています。 –

+0

ヌルの子を持つノードをコピーする場合、そのコピーにヌルの子が元の場所にあった対応するスロットのノードの内容は何ですか? – HostileFork

答えて

1

問題は、copy機能にあります。デフォルトコンストラクタで構築され、空のOctree octについては

node* n2 = new node; 

if (n) { 
    for (int i = 0; i < 8; i++) 
     n2->child[i] = copy(n->child[i]); 
} 
return n2; 

、および他のOctreeにコピー:のは、ステップバイステップを通してそれを行ってみよう

  1. 新しいnodeが作成され、n2
  2. nがありますrootoctなので、条件は次のとおりです。true
  3. child[i]n2は、対応する子のcopyの値を持っているので、新しいノードn2
  4. nを作成している
  5. 再びcopyを呼び出すことnullptroct内のすべてのnullptr子供ため)なので、条件
  6. を実行しません。
  7. 戻りn2
  8. 繰り返し、3から6 8回
  9. 戻るルートn2
  10. ステップ
  11. は、コピーされたオブジェクト

rootに新しいポインタ(n2)を割り当てしかし、待って!子がnullptrと想定されていても、手順6で新しいポインタを入力すると、returnが表示されます。

clearには、それぞれの子をループするので、それは問題です。それはまだOKですよね?しかし、あなたは初期化されていない子供たちにアクセスしようとします(無作為な値を持っていて、状態はtrueと評価されます)ので、あなたの記憶ではないのでRead access violationになります。

したがって、の解決策nnullptrでない場合にのみ、n2のためにメモリを割り当ててください。

+0

上記のコードを編集しました。それはあなたが手に入れたものですか?私がこのようにしている場合、「読み取りアクセス違反」はありませんが、コピーされたツリーの値は元のものと同じではありません。 –

+0

@ T.dogはい。質問の元のコードを更新しないでください。 – Rakete1111

+0

@ T.dogをコピーしていないため、 – 0x499602D2

関連する問題