C ++ указатели или память

0

Мой код кажется, что он должен работать с учетом алгоритма, но я новичок в C++, и кажется, что эти указатели переписываются, когда я вызываю insert несколько раз. Например, если я вызову insert со значениями 1, 3, 5, то корень будет равен 1 (как и ожидалось), но 3 будет перезаписано, а правый дочерний корень будет иметь значение 5 вместо 3.

virtual bool insert(const Data& item) {
if(root == NULL){
  BSTNode<Data> newNode (item);
  root = &newNode;
  isize++;
  return true;
}
BSTNode<Data>* nextNode = root;
BSTNode<Data>* prevNode = NULL;
bool isLeft;
while(nextNode!=NULL) {
  if (item < nextNode->data) {
    prevNode = nextNode;
    nextNode = nextNode->left;
    //std::cout << prevNode->data;
    isLeft = true;
  }
  else {
    prevNode = nextNode;
    nextNode = nextNode->right;
    //std::cout << prevNode->data;
    isLeft = false;
  }
}
BSTNode<Data> createNode (item);
createNode.parent = prevNode;
if (isLeft) prevNode->left = &createNode;
else prevNode->right = &createNode;
isize++;
return true;
}
Теги:
pointers
memory

2 ответа

2

У вас есть недопустимый указатель из-за указания на локальный объект, который собирается уничтожить:

BSTNode<Data> newNode (item);
root = &newNode;

Объект newNode является локальным объектом в методе insert после возврата из этого метода (он выходит за рамки), root указателя указывает на уничтоженный объект. Наивная возможность решить проблему - выделить newNode в кучу new:

root = new BSTNode<Data>(item);

но вы должны delete его где-нибудь, а также createNode же проблему для createNode.


Как рекомендовано многими, вы должны использовать смарт-точки, такие как unique_ptr и shared_ptr.

  • 1
    Хорошее замечание об удалении тоже ;-)
0

Предполагая, что root является переменной-членом, вам нужно выделить его в кучу, а не в стеке:

if(root == NULL){
  root = new BSTNode<Data>(item);
  isize++;
  return true;
}

В противном случае узел уничтожается, когда он выходит из области видимости в закрывающей скобке тела if. То же самое касается

if (isLeft) prevNode->left = new BSTNode<Data>(item);
else prevNode->right = new BSTNode<Data>(item);

Однако я не проверял вашу фактическую логику вставки. Вы должны опубликовать весь код, здесь слишком мало, чтобы проверить его. Это бинарное дерево?

Изменение: не забудьте удалить узлы, если вы создадите их в куче, в соответствии с ответом MM.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню