2015-11-27 7 views
0

DebugAssertionFailedОшибка отладки! Weird вопрос

AccessViolation

Две фотографии выше показывают ошибка Im имея. Порядок, в котором они находятся, - это порядок, в котором они появляются. Когда появляется первый, я нажимаю повтор, затем появляется второй, и я нажимаю «Продолжить», затем он повторяется, когда я наконец сломаюсь, вкладка отображается под названием «msvcr120d.i386.pdb не загружена». Когда программа прерывается, она указывает мне следующую строку: код «DynamicQueue.h»: «delete temp;»

Все dynamicqueue.h и большая часть BinaryTree.h копируются прямо из книги, поэтому я не знаю, что вызывает проблему (главным образом потому, что я понятия не имею, в чем проблема). Части BinaryTree.h, которые включают преобразование в Dynamic Queue, были написаны мной.

Ниже мой код:

DynamicQueue.h

#ifndef DYNAMICQUEUE_H 
#define DYNAMICQUEUE_H 

#include <iostream> 
using namespace std; 

//Dynamic Queue Template 
template <class T> 
class DynamicQueue{ 
private: 
    struct QueueNode{ 
     T value; 
     QueueNode* next; 
    }; 

    QueueNode* front; 
    QueueNode* rear; 
    int numItems; 

public: 
    //Constructor 
    DynamicQueue(); 

    //Destructor 
    ~DynamicQueue(); 

    //Queue Operations 
    void enqueue(T); 
    void dequeue(T &); 
    bool isEmpty() const; 
    bool isFull() const; 
    void clear(); 
}; 


//Constructor 
template <class T> 
DynamicQueue<T>::DynamicQueue(){ 
    front = nullptr; 
    rear = nullptr; 
    numItems = 0; 
} 



//Destructor 
template <class T> 
DynamicQueue<T>::~DynamicQueue(){ 
    clear(); 
} 



//enqueue 
template <class T> 
void DynamicQueue<T>::enqueue(T item){ 
    QueueNode* newNode = nullptr; 

    newNode = new QueueNode; 
    newNode->value = item; 
    newNode->next = nullptr; 

    if (isEmpty()){ 
     front = newNode; 
     rear = newNode; 
    } 
    else{ 
     rear->next = newNode; 
     rear = newNode; 
    } 

    numItems++; 
} 



//Dequeue 
template <class T> 
void DynamicQueue<T>::dequeue(T &item){ 
    QueueNode* temp = nullptr; 

    if (isEmpty()) 
     cout << "The queue is empty.\n"; 
    else{ 
     item = front->value; 
     temp = front; 
     front = front->next; 
     delete temp; //When the program breaks, it points me here.... 

     numItems--; 
    } 
} 



//isEmpty 
template <class T> 
bool DynamicQueue<T>::isEmpty() const{ 
    return !numItems > 0; 
} 




//clear 
template <class T> 
void DynamicQueue<T>::clear(){ 
    T value; 
    while (!isEmpty()) 
     dequeue(value); 
} 


#endif 

BinaryTree.h

#ifndef BINARYTREE_H 
#define BINARYTREE_H 

#include <iostream> 
#include "DynamicQueue.h" 

using namespace std; 

//BinaryTree Template 
template <class T> 
class BinaryTree{ 
private: 
    struct TreeNode{ 
     T value; // TThe value in the node 
     TreeNode* left; //Pointer to the left child node 
     TreeNode* right; //Pointer to the right child node 
    }; 

    TreeNode* root; //Pointer to the root node 

    //Private methods 
    void insert(TreeNode *&, TreeNode *&); 
    void destroySubtree(TreeNode *&); 
    void deleteNode(T, TreeNode *&); 
    void makeDeletion(TreeNode *&); 
    void displayInOrder(TreeNode *) const; 
    void displayPreOrder(TreeNode *) const; 
    void displayPostOrder(TreeNode *) const; 
    void loadInQueue(DynamicQueue<T>, TreeNode *); 


public: 
    //Constructor 
    BinaryTree(){ 
     root = nullptr; 
    } 

    //Destructor 
    ~BinaryTree(){ 
     destroySubtree(root); 
    } 

    //Binary Tree Operations 
    void insertNode(T); 
    bool searchNode(T); 
    void remove(T); 

    void displayInOrder() const{ 
     displayInOrder(root); 
    } 

    void displayPreOrder() const{ 
     displayPreOrder(root); 
    } 

    void diplayPostOrder() const{ 
     displayPostOrder(root); 
    } 

    void convertToQueue(DynamicQueue<T> &); 
}; 


//Insert Method 
template <class T> 
void BinaryTree<T>::insert(TreeNode* &nodePtr, TreeNode* &newNode){ 
if (nodePtr == nullptr) 
nodePtr = newNode; //Insert the node 
else if (newNode->value < nodePtr->value) 
    insert(nodePtr->left, newNode); //Search the left branch 
else 
insert(nodePtr->right, newNode); //Search the right branch 
} 


//insertNode 
template <class T> 
void BinaryTree<T>::insertNode(T item){ 
    TreeNode* newNode = nullptr; 

    //Create a new Node and store val in it 
    newNode = new TreeNode; 
    newNode->value = item; 
    newNode->left = newNode->right = nullptr; 

    //Insert the node 
    insert(root, newNode); 
} 


//DestorySubTree 
template <class T> 
void BinaryTree<T>::destroySubtree(TreeNode* &nodePtr){ 
    if (nodePtr){ 
     if (nodePtr->left) 
      destroySubtree(nodePtr->left); 
     if (nodePtr->right) 
      destroySubtree(nodePtr->right); 

     delete nodePtr; 
    } 
} 



//searchNode 
template <class T> 
bool BinaryTree<T>::searchNode(T item){ 
    TreeNode* nodePtr = root; 

    while (nodePtr){ 
     if (nodePtr->value == item) 
      return true; 
     else if (item < nodePtr->value) 
      nodePtr = nodePtr->left; 
     else 
      nodePtr = nodePtr->right; 
    } 
    return false; 
} 



//remove 
template <class T> 
void BinaryTree<T>::deleteNode(T item, TreeNode* &nodePtr){ 
    if (item < nodePtr->value) 
     deleteNode(item, nodePtr->left); 
    else if (item > nodePtr->value) 
     deleteNode(item, nodePtr->right); 
    else 
     makeDeletion(nodePtr); 
} 



template <class T> 
void BinaryTree<T>::makeDeletion(TreeNode* &nodePtr){ 
    TreeNode* tempNodePtr = nullptr; 
    if (nodePtr == nullPtr) 
     cout << "Cannot delete empty node.\n"; 
    else if (nodePtr->right == nullptr){ 
     tempNodePtr = nodePtr; 
     nodePtr = nodePtr->left; 
     delete tempNodePtr; 
    } 
    else if (nodePtr->left == nullptr){ 
     tempNodePtr = nodePtr; 
     nodePtr = nodePtr->right; 
     delete tempNodePtr; 
    } 
    else{ 
     tempNodePtr = nodePtr->right; 
     while (tempNodePtr->left) 
      tempNodePtr = tempNodePtr->left; 
     tempNodePtr->left = nodePtr->left; 
     tempNodePtr = nodePtr; 
     nodePtr = nodePtr->right; 
     delete tempNodePtr; 
    } 
} 



//displayInOrder 
template <class T> 
void BinaryTree<T>::displayInOrder(TreeNode* nodePtr) const{ 
    if (nodePtr){ 
     displayInOrder(nodePtr->left); 
     cout << nodePtr->value << endl; 
     displayInOrder(nodePtr->right); 
    } 
} 



//displayPreOrder 
template <class T> 
void BinaryTree<T>::displayPreOrder(TreeNode* nodePtr) const{ 
    if (nodePtr){ 
     cout << nodePtr->value << endl; 
     displayPreOrder(nodePtr->left); 
     displayPreOrder(nodePtr->right); 
    } 
} 


//displayPostOrder 
template <class T> 
void BinaryTree<T>::displayPostOrder(TreeNode* nodePtr) const{ 
    if (nodePtr){ 
     displayPostOrder(nodePtr->left); 
     displayPostOrder(nodePtr->right); 
     cout << nodePtr->value << endl; 
    } 
} 

//ConvertToQueue 
template <class T> 
void BinaryTree<T>::convertToQueue(DynamicQueue<T> &queue){ 
    queue.clear(); 
    loadInQueue(queue, root); 
} 

//LoadInQUEUE 
template <class T> 
void BinaryTree<T>::loadInQueue(DynamicQueue<T> queue, TreeNode* nodePtr){ 
    if (nodePtr){ 
     loadInQueue(queue, nodePtr->left); 
     queue.enqueue(nodePtr->value); 
     loadInQueue(queue, nodePtr->right); 
    } 
} 

#endif 

ConvertBinaryTreeToQueue.cpp

#include "stdio.h" 
#include "conio.h" 
#include "BinaryTree.h" 
#include "DynamicQueue.h" 

using namespace std; 


void main(){ 

    BinaryTree<int> tree; 

    for (int i = 0; i < 10; i++){ 
     tree.insertNode(i * 5); 
    } 

    DynamicQueue<int> queue; 
    tree.convertToQueue(queue); 

    while (!queue.isEmpty()){ 
     int value; 
     queue.dequeue(value); 
     cout << value << endl; 
    } 

    _getch(); 

} 

Если кто-то может помочь я решаю или, по крайней мере, пойму, я бы очень признателен за это :)

Примечание: я исхожу из фона Java, у меня были проблемы, прежде чем я попытаюсь сделать что-то, что работает в Java, но не работает на C++, поэтому я не удивлюсь, если это снова станет проблемой, но я обычно получаю более стандартизированные сообщения об ошибках, когда это происходит.

+0

Не размещайте ссылки на изображения. Опубликуйте текст сообщений об ошибках. Вы также должны вызывать отладчик и сообщать о строке, вызывающей проблему. –

+0

Ну, проблема в том, что это не дает мне строку, которая вызывает проблему. Программа компилируется, а затем, когда она ломается, она точно не говорит. – A20T3M4

+0

Нажмите «Повторить попытку» для отладки приложения. –

ответ

0

Обе ошибки связаны с вашей программой, пытаясь получить доступ к памяти, чтобы она не была разрешена (не более).

В этой функции convertToToQueue вы создаете новый DynamicQueuenewQueue называется, что разрушается, когда объем этой функции заканчивается:

//ConvertToQueue 
template <class T> 
void BinaryTree<T>::convertToQueue(DynamicQueue<T> &queue){ 
    DynamicQueue<T> newQueue; 
    loadInQueue(newQueue, root); 

    queue = newQueue; 
} 

Назначение newQueue в queue не собирается делать то, что вы могли бы ожидать. В классе DynamicQueue отсутствует экземпляр-конструктор, поэтому компилятор сделает его для вас в меру своих знаний. Он копирует значения front, rear и numItems.

Когда newQueue выходит из области видимости, все QueueNode объекты в ней будут удалены (поскольку деструктор DynamicQueue вызовов clear();). На данный момент queue.front и queue.end указывают на недопустимую память.

Вместо создания нового DynamicQueue вы должны передать в аргументе queue. Если вы хотите, чтобы убедиться, что queue содержит только элементы от BinaryTree, вы можете позвонить по телефону queue.clear();, прежде чем звонить loadInQueue.

+0

Спасибо за совет. Совет был полезен для улучшения дизайна, но, похоже, он не решает проблему. У меня есть метод обновления, но он, похоже, дает мне ту же проблему. Редактировать: Я обновил код с исправлением. – A20T3M4

+0

Обновление: после немного более тонкой настройки с этим новым советом, я получил работу. Спасибо огромное! – A20T3M4