Для моего текущего программирования я должен построить двоичное дерево поиска и использовать его для вставки слов из файла в алфавитном порядке, чтобы составить список соответствия. Программа завершена и выводится правильно; основная часть программы работает отлично. Но когда программа заканчивается и вызываются деструкторы, она вылетает с error in ./concordancebst : free(): invalid pointer
. Я не понимаю, в чем проблема, мой деструктор выглядит так, как будто он работает, и глядя на код онлайн, кажется, что он тоже должен работать. Я мог бы обойти это, используя std::unique_ptr
, но он, похоже, немного переборщил в смысле объема программы (также излишний в том смысле, что мы не охватили интеллектуальные указатели, все, что мы сделали в классе, включающем динамическую память был обработан посредством ручного распределения/освобождения).Двоичный древовидный древовидный поиск: free() недействительный указатель
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;
}
[А где ваш ** 'INT основной()' **] (http://stackoverflow.com/help/mcve)? «основной», как в «полной». –
Off topic: Сохраните немного ввода и часовой цикл или два. 'Node() {word =" "; count = 0; left = nullptr; right = nullptr;} 'может быть' Node(): word (""), count (0), left (nullptr), right (nullptr) {} ' – user4581301
Ошибка, которую вы сказали, что у вас есть упоминания' свободный' функция неисправность. Я не вижу вызов функции 'free' в фрагменте кода, который вы вставили. Вы уверены, что показываете нам соответствующий код? С другой стороны, можете ли вы, случайно, освободить память «свободным», когда эта память была выделена «новым»? –