2016-05-16 2 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 функции I 'm дает значение для узла номер 8 в первом дереве. После этого я вызываю конструктор копирования и печатаю восьмой узел второго дерева. Значение такое же, что я дал для первого дерева, но когда назвал дескриптор, я всегда получал это исключение:

Исключение брошено: нарушение прав на чтение. узел был 0xDDDDDDDD.

Как я знаю, это означает, что я попытался удалить узлы, которые я уже удалил. Объект «tree2» - это другой объект из «дерева» с теми же значениями и узлами, не так ли? Тогда я не понимаю этого исключения выше. Я новичок в C++, и я знаю, что это основной материал, поэтому, если кто-то направит меня в правильном направлении, я бы очень признателен.

+1

Не следует «копировать» return '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. Новый node создан, n2
  2. n является root от oct, поэтому условие, если true
  3. child[i] of n2 имеет значение copy соответствующего ребенка, так называют copy снова
  4. Новый узел n2 создается
  5. n является nullptr (потому что дети, где все nullptr в oct), так что не выполняют условие
  6. Возвращение n2
  7. Повторите шаги 3 в 6 8 раз
  8. Верните корень n2
  9. Присвоить новый указатель (n2) для root скопированного объекта

Но подождите! Вы заметили, что на шаге 6 вы указали новый указатель, хотя ребенок должен быть nullptr!

В этом проблема, потому что тогда, в clear, вы пройдете через каждого ребенка. Это все в порядке, не так ли?Но тогда вы пытаетесь получить доступ к детям, которые неинициализированы (они имеют случайное значение, условие будет оцениваться до true), поэтому вы получаете Read access violation, потому что это не ваша память.

Таким образом, решение ? Распределите память только для n2, если n не nullptr.

+0

Я редактировал мой код выше. Это то, за что вы боролись? Если я делаю это так, нет «нарушения доступа к чтению», но значение скопированного дерева не совпадает с исходным. –

+0

@ T.dog да, потому что вы не копируете значение – Rakete1111

+0

@ T.dog Не обновляйте исходный код в вопросе. – 0x499602D2

Смежные вопросы