【发布时间】:2015-11-24 19:25:48
【问题描述】:
对于我当前的编程任务,我必须构建一个二叉搜索树,并使用它按字母顺序从文件中插入单词,以制作索引列表。程序完整,输出正确;该程序的主要部分完美运行。但是当程序完成并调用析构函数时,它会因error in ./concordancebst : free(): invalid pointer 而崩溃。我不知道问题出在哪里,我的析构函数看起来可以工作,并且在线查看代码似乎也应该可以工作。我可能可以通过使用std::unique_ptr 来解决这个问题,但从程序范围的角度来看,这似乎有点矫枉过正(在我们没有涵盖智能指针的意义上也是矫枉过正,我们在课堂上所做的一切都涉及动态内存已通过手动分配/解除分配处理)。
BST.h
#ifndef BST_H
#define BST_H
#include <string>
class BST {
public:
BST() { root = nullptr; }
~BST();
void insert(const std::string word);
int getCount(const std::string word);
int length();
friend std::ostream& operator << (std::ostream &out_s, BST b);
private:
struct Node {
std::string word;
int count;
Node *left;
Node *right;
Node() { word = ""; count = 0; left = nullptr; right = nullptr;}
~Node();
};
Node *root;
void RInsert(Node* &t, std::string word);
int countNodes(Node *p);
void print(Node *p, std::ostream &out_s);
};
#endif
BST.cpp
#include "BST.h"
#include <string>
#include <iostream>
#include <iomanip>
BST::Node::~Node() {
delete left;
delete right;
}
BST::~BST() {
delete root;
}
int BST::countNodes(Node *p) {
if(p == nullptr)
return 0;
else
return countNodes(p->left) + countNodes(p->right) + 1;
}
int BST::getCount(const std::string word) {
Node *p = root;
while(true) {
if(p == nullptr)
return 0;
else if(word.compare(p->word) < 0)
p = p->left;
else if(word.compare(p->word) == 0)
return p->count;
else
p = p->right;
}
}
int BST::length() {
return countNodes(root);
}
void BST::RInsert(Node* &t, std::string word) {
if(t == nullptr) {
t = new Node;
t->word = word;
t->left = nullptr;
t->right = nullptr;
t->count++;
}
else if(word.compare(t->word) == 0)
t->count++;
else if(word.compare(t->word) < 0)
RInsert(t->left, word);
else //word.compare(t->word > 0)
RInsert(t->right, word);
}
void BST::insert(const std::string word) {
RInsert(root, word);
}
void BST::print(Node *p, std::ostream &out_s) {
if(p != nullptr) {
print(p->left, out_s);
out_s << std::setw(13) << p->word << std::setw(10) << p->count << std::endl;
print(p->right, out_s);
}
}
std::ostream &operator << (std::ostream &out_s, BST b) {
out_s << std::setw(13) << "Word" << std::setw(10) << "Count" << std::endl;
out_s << "---------------------------------------------" << std::endl;
b.print(b.root, out_s);
out_s << "---------------------------------------------" << std::endl;
out_s << "The file contains " << b.length() << " distinct words." << std::endl;
return out_s;
}
【问题讨论】:
-
And where is your
int main()? “主要”与“完成”一样。 -
题外话:节省一点打字时间和一两个时钟周期。
Node() { word = ""; count = 0; left = nullptr; right = nullptr;}可以是Node(): word(""), count(0), left(nullptr), right(nullptr){} -
您所说的错误,您提到
free函数失败。我在您粘贴的代码 sn-p 中没有看到free函数调用。您确定要向我们展示相关代码吗?在旁注中,当内存由new分配时,您是否有机会使用free释放内存? -
@AlgirdasPreidžius 好点值得探索,但在
delete的阴暗面深处,人们经常会找到free。 -
MCVE 有两个很好的理由:它迫使提问者更深入地调查他们的代码和问题。通常情况下,构建最小案例会暴露错误并省去提出问题的麻烦。能够导出最少的代码是一项重要的调试技能,可能就在使用调试器之后。其次,MCVE 允许任何人将程序代码粘贴到他们选择的 IDE 中,并直接查看问题所在。它消除了复制提问者使用的测试用例所涉及的猜测,也消除了想知道错误是否在未显示的代码中所浪费的时间。
标签: c++ c++11 binary-search-tree destructor