Копируй конструктор и деструктор 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 в первом дереве. После этого я вызываю конструктор копирования и печатаю восьмой узел второго дерева. Значение то же, что я дал для первого дерева, но когда вызывался дескриптор, я всегда получал это исключение:
Исключение: нарушение прав на чтение. узел был 0xDDDDDDDD.
Как я знаю, это означает, что я пытался удалить узлы, которые я уже удалил. Объект "tree2" отличается от "дерева" с теми же значениями и узлами, не так ли? Тогда я не понимаю это исключение выше. Я новичок в C++ и знаю, что это базовые вещи, поэтому, если кто-то направит меня в правильном направлении, я буду очень признателен.
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
:
- Новый
node
создано,n2
n
этоroot
изoct
, так что условие, еслиtrue
child[i]
изn2
имеет значениеcopy
соответствующего ребенка, так что позвонитеcopy
снова- Новый узел
n2
создано n
являетсяnullptr
(потому что дети, где всеnullptr
вoct
), поэтому не выполняйте условие- Вернуть
n2
- Повторите шаги
3
в6
8 раз - Вернуть рут
n2
- Назначить новый указатель (
n2
) чтобыroot
скопированного объекта
Но ждать! Вы заметили, что на шаге 6 вы return
новый указатель, хотя предполагается, что ребенок nullptr
!
Это проблема, потому что тогда, в clear
перебери каждого ребенка. Это все еще хорошо, верно? Но затем вы пытаетесь получить доступ к дочерним элементам, которые не были инициализированы (они имеют случайное значение, условие оценивается как true
), так что вы получите Read access violation
потому что это не твоя память.
Итак, решение? Выделите только память для n2
если n
не является nullptr
,