【发布时间】:2018-04-13 21:17:36
【问题描述】:
所以我正在为我的 c++ 类创建一个二进制最大堆,我一直遇到这个异常,说我在我的类方法中返回了一个 nullptr。我很难找到它在我的代码中的位置,因此我们将不胜感激任何帮助。不断抛出的异常如下:
Unhandled exception thrown: read access violation.
**std::_String_alloc<std::_String_base_types<char,std::allocator<char> > ::_Get_data**(...) returned nullptr. occurred
这是我的树头文件: #ifndef HEAP_H #define HEAP_H
#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
这是我的 Node 的 .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;
}
提前感谢您提供的任何帮助。
【问题讨论】:
-
您是否尝试过使用调试器单步执行您的代码?
-
我已经经历了一些,但我并不完全精通 Visual Studio 调试器
-
无法编译
-
不,它不编译
-
@Conrad2098 你需要精通它。但这很简单。在您认为可能出现错误的地方设置一些断点。并运行您的代码。然后使用“step over”逐行遍历你的代码,直到它最终抛出错误然后你知道它发生在哪里,然后可以找出为什么。
标签: c++ exception heap binary-tree