Указатель - это просто переменная, которая содержит адрес объекта в памяти.Когда вы определяете указатель, например
int *foo;
, вы не инициализируете его, поэтому его значение является неопределенным.Это означает, что он не содержит действительного значения указателя, которое можно использовать для доступа к объекту в памяти.Чтобы на самом деле сделать указатель указать на что-то, вам нужно присвоить ему адрес:
int bar;
inf *foo = &bar;
Теперь foo
содержит адрес bar
, и вы можете разыменовать foo
написать в bar
:
*foo = 42;
// bar is now 42
В вашем коде
TreeNode *root;
root->data = 5;
Вы пытаетесь разыменовать (root->data
- просто синтаксический сахар для (*root).data
) указатель root
, который не был инициализирован или ему не присвоено правильное значение указателя.
Поскольку вы хотите создать динамическую структуру данных, которая увеличивается по требованию, вы хотите выделить память во время выполнения.Вы можете сделать это, используя оператор new
:
TreeNode *root = new TreeNode; // allocates an object of the type
// TreeNode
root->data = 5; // is now safe.
Но так как вы предоставляете конструктор для TreeNode
, который принимает int
, вы можете написать:
TreeNode *root = new TreeNode{ 5 };
То же самое относится и ко многим другим местам в вашем коде.
Пожалуйста, помните, что динамически выделенная память должна быть освобождена, когда она больше не нужна:
`delete root;`