2017-11-01 5 views
-1

私はC++クラスのバイナリの最大ヒープを作成しています。この例外が発生しても、クラスメソッドでnullptrが返されています。私はコード内でどこにあるのかを見つけるのが難しいので、どんな助けでも大歓迎です。次のように投げ続ける例外は次のとおりです。C++バイナリmaxヒープ読み取りアクセス違反

Unhandled exception thrown: read access violation. 
**std::_String_alloc<std::_String_base_types<char,std::allocator<char> > ::_Get_data**(...) returned nullptr. occurred 

はここに木のための私のヘッダファイルです:

:HEAP_H の#define HEAP_H #ifndefの

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

    class TreeHeap { 
    private: 
     THeapNode *root; // the top node of the heap 

     int next_loc; // the next valid location to place a node 

     void bubble_up(THeapNode *node); //performs the bubble up operation on the given node 

     void bubble_down(THeapNode *node); //performs the bubble down operation on the given node 

     void clear_heap(THeapNode *node); // removes all elements from the heap 




    public: 

     TreeHeap(); // the constructor 

     ~TreeHeap(); // the destructor 

     THeapNode* find_node(const int position); // finds the node in the position given and returns a pointer to it 

     void insert(const string &item); // creates a node with the string given as the value and places it in the next location 

     bool Delete(); // removes the root of the heap and returns false if the tree is empty 
    }; 

    #endif 

は、ここに私のノードの.hファイルです

#ifndef NODE_H 
    #define NODE_H 
    #include<string> 
    using std::string; 

    struct THeapNode { 
     string data; // stores a data string 
     THeapNode *parent; // a pointer to the parent node 
     THeapNode *rightChild;  // a pointer to the right child node 
     THeapNode *leftChild; // a pointer to the left child node 
     THeapNode(const string &str); 
    }; 

    #endif 

私の.cppファイルは次のとおりです。

#include "stdafx.h" 
    #include <cmath> 
    #include "TreeHeap.h" 
    #include "THeapNode.h" 


    TreeHeap::TreeHeap() { 
     root = NULL; 
     next_loc = 1; 
    }; 

    TreeHeap::~TreeHeap() { 

     THeapNode *current = root; 
     THeapNode *deleteNode = NULL; 
     int d = floor(log2(next_loc - 1)); 
     int j = next_loc; 

     for (int i = 1; i <= j-1; i++) { 

      while (1) { 

       int d = floor(log2(next_loc - i)); 
       int power = std::pow(2, d - 1); 

       if (next_loc == 1) { 
        deleteNode = current; 
        j -= 1; 
       } 
       else if (next_loc < (std::pow(2, d - 1) * 3)) { 
        current = current->leftChild; 
       } 
       else { 
        current = current->rightChild; 
       } 

       // Update location and depth to reflect traversal 
       next_loc = std::pow(2, d - 1) + next_loc % power; 
       d = d - 1; 
      } 

      clear_heap(deleteNode); 

     } 

    } 

    void TreeHeap::clear_heap(THeapNode *node) { 

     if (node == NULL) { 
      return; 
     } 

     node->data = ""; 
     node->leftChild = NULL; 
     node->rightChild = NULL; 
     node->parent = NULL; 

    } 

    void TreeHeap::insert(const string &value) { 

     THeapNode newNode = THeapNode(value); 
     int loc = next_loc; 

     if (loc == 1) { 
      *root = newNode; 
     } 

     THeapNode *current = root; 

     while (1) { 

      int d = floor(log2(loc)); 
      int power = std::pow(2, d - 1); 

      if (loc < (power * 3)) { 
       if (current->leftChild = nullptr) { 
        *current->leftChild = newNode; 
        newNode.parent = current; 
        next_loc += 1; 
        break; 
       } 
       else { 
        current = current->leftChild; 
       } 
      } 

      else { 
       if (current->rightChild = nullptr) { 
        *current->rightChild = newNode; 
        newNode.parent = current; 
        next_loc = +1; 
        break; 
       } 
       else { 
        current = current->rightChild; 
       } 
      } 

      // Update location and depth to reflect traversal 
      loc = std::pow(2, d - 1) + loc % power; 
      d = d - 1; 

     } 
     std::cout << current->data << "\n"; 
     system("PAUSE"); 

    } 

    void TreeHeap::bubble_up(THeapNode *node) { 

     if (node == NULL) { 
      return; 
     } 

     THeapNode *parent = node->parent; 

     while (parent->data < node->data) { 
      parent = node->parent; 
      string temp = parent->data; 
      parent->data = node->data; 
      node->data = temp; 
      } 

    } 

    void TreeHeap::bubble_down(THeapNode *node) { 

     if (node == NULL) { 
      return; 
     } 

     while(node->data < node->rightChild->data || node->data < node->leftChild->data){ 
      if (node->rightChild->data > node->leftChild->data) { 

       THeapNode *right = node->rightChild; 
       string temp = right->data; 
       right->data = node->data; 
       node->data = temp; 
      } 
      else if (node->rightChild->data < node->leftChild->data) { 

       THeapNode *left = node->leftChild; 
       string temp = left->data; 
       left->data = node->data; 
       node->data = temp; 
      } 
     } 
    } 

    THeapNode* TreeHeap::find_node(const int position){ 

     int loc = position; 
     int d = floor(log2(position)); 
     int power = std::pow(2, d - 1); 
     THeapNode *returnValue = root; 

     while (returnValue != NULL && 1 < position && position < (next_loc - 1)) { 

      if (loc == 1) { 
       return returnValue; 
      } 
      else if (loc < (std::pow(2, d-1) * 3)) { 
       returnValue = returnValue->leftChild; 
      } 
      else { 
       returnValue = returnValue->rightChild; 
      } 

      // Update location and depth to reflect traversal 
      loc = std::pow(2, d - 1) + loc % power; 
      d = d - 1; 
     } 
     std::cout << returnValue->data<<"\n"; 
     return returnValue; 
    } 

    bool TreeHeap::Delete() { 

     if (next_loc = 1) { 
      return false; 
     } 

     int d = floor(log2(next_loc - 1)); 
     THeapNode *current = root; 
     THeapNode *usedNode = NULL; 
     int loc = next_loc - 1; 

     while (1) { 

      int d = floor(log2(loc)); 
      int power = std::pow(2, d - 1); 

      if (loc == 1) { 
       usedNode = current; 
       break; 
      } 
      else if (loc < (std::pow(2, d - 1) * 3)) { 
       current = current->leftChild; 
      } 
      else { 
       current = current->rightChild; 
      } 

      // Update location and depth to reflect traversal 
      loc = std::pow(2, d - 1) + loc % power; 
      d = d - 1; 
     } 



     THeapNode *temp = root; 
     clear_heap(root); 
     root = usedNode; 
     delete temp; 

     bubble_down(root); 

     return true; 
    } 

ご協力いただきありがとうございます。

+1

デバッガでコードをステップ実行しようとしましたか? – Javia1492

+0

私は幾分それを通り抜けましたが、私はビジュアルスタジオデバッガに堪能ではありません – Conrad2098

+0

はコンパイルされません – OznOg

答えて

0

あなたのbubble_upbubble_down機能では、クイック検査でエラーが表示されます。 bubble_up

、次のしている:これは、ノードが先頭にすべての道を泡とき、それはルートにあるノードをチェックしないので、失敗しようとしている

THeapNode *parent = node->parent; 

    while (parent->data < node->data) { 
     parent = node->parent; 
     string temp = parent->data; 
     parent->data = node->data; 
     node->data = temp; 
     } 

。あなたは記述する必要があります:あなたはrightChildまたはleftChild NULLかどうかをチェックしません

while(node->data < node->rightChild->data || node->data < node->leftChild->data){ 
     if (node->rightChild->data > node->leftChild->data) { 

bubble_down

while (parent != NULL && parent->data < node->data) 

、あなたはこのコードを持っています。

nodeの値を決して変更しないので、もっと重要なのは、私にとって無限ループのように見えます。

これは、あなたのコードを素早く読んだときに見たエラーです。もっとあるかもしれない。

関連する問題