2016-11-09 3 views
0

Я пытаюсь создать дерево структур и вставить мои данные для узлов дерева в структуру, которая содержит два носителя данных. Мои дерево/структуры данных выглядят так:Ошибка доступа к памяти Вставка структуры в Tree Struct C++

class BinarySearchTree 
{ 
private: 

struct IndexEntry 
{ 
    int acctID; // (key) Account identifier 
    long recNum; // Record number 
}; 

struct tree_node 
{ 
    IndexEntry* entry; 
    tree_node* left; 
    tree_node* right; 
}; 
tree_node* root; 

public: 
BinarySearchTree() 
{ 
    root = NULL; 
} 

bool isEmpty() const { return root == NULL; } 
void insert(int, int); 
int search(int); 
int treeSearch(tree_node*, int); 
}; 

Я получаю нарушение доступа к памяти в данный момент в моей функции вставки, и, честно говоря, это первый раз, когда я пытаюсь деревом структур так Я не знаю, действительно ли это правильная функция вставки. Но вот это:

void BinarySearchTree::insert(int rNum, int aNum) 
{ 
tree_node* t = new tree_node; 
tree_node* parent; 
t -> entry -> recNum = rNum; //right here I get a violation 
t -> entry -> acctID = aNum; //but if I remove the assignments 
t -> left = NULL;   //it gives me a violation further down 
t -> right = NULL; 
parent = NULL; 

if (isEmpty()) 
    root = t; 
else 
{ 
    tree_node* current; 
    current = root; 
    // Find the Node's parent 
    while (current) 
    { 
     parent = current; //This whole block will give me a memory violation 
     if (t -> entry -> recNum > current -> entry -> recNum) 
      current = current -> right; 
     else current = current -> left; 
    } 

    if (t -> entry -> recNum < parent -> entry -> recNum) 
     parent -> left = t; 
    else 
     parent -> right = t; 
} 
} 

Пожалуйста, обратитесь к моим комментариям во втором блоке кода для расположения нарушений доступа к памяти. Я думаю, что в коде есть что-то неинициализированное, но я не знаю, где это будет и как его инициализировать.

Любая помощь или направление будут оценены!

+0

Вы никогда не инициализируется ' t-> entry'. – Barmar

+1

Не помещайте пробелы вокруг '->', это не идиоматично. – Barmar

+0

Специально не смешивайте его с оператором '>'. Похож на стрелу. –

ответ

0

Вы разыменования не инициализирован указатель. Когда вы это сделаете:

tree_node* t = new tree_node; 

тогда компилятор выполнит конструктор по умолчанию, который на самом деле ничего не делает. t->entry не присвоено никакого значения и содержит мусор.

Так позже, когда вы разыменования его с:

t -> entry -> recNum = rNum; //right here I get a violation 

(t -> entry -> это операция разыменования), вы получаете Неопределенное поведение, которое в результатах дела в аварии.

Решение заключается в инициализации t -> entry перед разыменованием его.

0

вам необходимо инициализировать t->entry

tree_node *t = new tree_node; 
t->entry = new IndexEntry; 
0

Указатель entry в tree_node не инициализирован правильно, это указатель и не указывает на действительный объект. Вы можете инициализировать его в конструкторе и не забудьте удалить его в деструкторе.

struct tree_node 
{ 
    IndexEntry *entry; 
    tree_node *left; 
    tree_node *right; 

    tree_node() : 
     entry(new IndexEntry), // create a new entry object 
     left(NULL), right(NULL) 
    {} 

    ~tree_node() 
    { 
     delete entry; // release the memory when we're done 
    } 
}; 

На самом деле, я не понимаю, почему вам нужно создать IndexEntry в куче, в первую очередь. Кажется entry является частью tree_node, так что вы можете просто «встраивать» это в tree_node:

struct tree_node 
{ 
    IndexEntry entry; // not a pointer, but an object 
    tree_node *left; 
    tree_node *right; 
}; 

Конечно, вы должны использовать . при обращении к членам из entry:

tree_node *t = new tree_node; 
t->entry.recNum = rNum; 
t->entry.acctID = aNum; 
t->left = NULL; 
t->right = NULL;