[英]Segmentation Fault in Custom map class
在C ++中為類分配實現自定義映射類。 程序編譯得很好,但是一旦程序試圖顯示鍵,它就會崩潰。
Map.h文件
#ifndef MAP_H
#define MAP_H
#include<string>
template<typename K, typename V>
class Map {
public:
Map();
~Map();
V& operator[](const K&);
void traverse(void(*f)(const K&, const V&));
private:
class Node{ //Node Class
public:
Node(K k=K(0), V v=V(0), Node* l = nullptr, Node* r = nullptr) :
Key(k), Value(v), left(l), right(r) {}
K Key;
V Value;
Node* left;
Node* right;
};
Node* head;
//Helper Functions
//
void traverseHelp(void(*f)(const K&, const V&), Node*);
Node* find(Node*, const K&) const;
Node* insert(Node*, const K&);
void deleteNodes(Node*);
};
#include"./Map.cc"
#endif
Map.cc文件
#include<iostream>
#include"Map.h"
#include<string>
using namespace std;
//Map Constructor & Destructor
//
template<typename K, typename V>
Map<K,V>::Map(){
head = nullptr;
}
template<typename K, typename V>
Map<K,V>::~Map(){
deleteNodes(head);
}
template<typename K, typename V>
void Map<K,V>::deleteNodes(Node* start){
if(start->left){
deleteNodes(start->left);
start->left=nullptr;
}
if(start->right){
deleteNodes(start->right);
start->right=nullptr;
}
if(start->left==nullptr && start->right==nullptr){
delete start;
start=nullptr;
}
}
//operator[] and Helpers
//
template<typename K, typename V>
V& Map<K,V>::operator[](const K& keyIn)
{
Node* temp= find(head,keyIn);
if(temp == nullptr)
{
temp = insert(head,keyIn);
cout << "inserted " << temp->Key << endl;
}
cout << "returning " << temp->Value << endl;
return temp->Value;
}
template<typename K, typename V>
typename Map<K,V>::Node* Map<K,V>::insert(Node* start, const K& keyIn){
Node* ptr = start;
if(ptr==nullptr)
{
ptr = new Node(keyIn, 0, nullptr, nullptr);
return ptr;
}
while(true){
if(ptr->Key>keyIn){
if(ptr->left==nullptr){
ptr->left = new Node(keyIn, 0, nullptr, nullptr);
return ptr->left;
}
else{
ptr = ptr->left;
continue;
}
}
else{
if(ptr->right==nullptr){
ptr->right = new Node(keyIn, 0, nullptr, nullptr);
return ptr->right;
}
else{
ptr = ptr->right;
continue;
}
}
}
}
template<typename K, typename V>
typename Map<K,V>::Node* Map<K,V>::find(Node* temp, const K& keyIn ) const
{
Node* ptr = temp;
while(true){
if(ptr==nullptr){
return ptr;
}
if(ptr->Key==keyIn){
return ptr;
}
if(ptr->Key>keyIn){
ptr = ptr->left;
continue;
}
else{
ptr = ptr->right;
continue;
}
}
}
//Traverse function & helper
//
template<typename K, typename V>
void Map<K,V>::traverseHelp(void (*f)(const K& keyIn, const V& valIn), Map<K,V>::Node* root){
cout << "got here 2 " << endl;
if(root->left==nullptr && root->right==nullptr){
cout << "Apply F" << endl;
f(root->Key, root->Value);
}
else if(root->left!=nullptr){
cout << "Traverse left" << endl;
traverseHelp(*f, root->left);
}
else if(root->right!=nullptr){
cout << "Traverse right" << endl;
traverseHelp(*f, root->right);
}
cout << "Got here 3" << endl;
}
template<typename K, typename V>
void Map<K,V>::traverse(void (*f)(const K& keyIn, const V& valIn)){
cout << "got here" <<endl;
traverseHelp(*f, head);
}
freq.cc
#include<iostream>
#include<iomanip>
#include<algorithm>
#include"Map.h"
#include<string>
using namespace std;
void printMap(const string&, const int&);
int main() {
string input;
Map<string, int> words;
//Input for map values
//
cout << "Enter words seperated by a new line. Type -1 to end" << endl;
cin >> input;
while(input != "-1") {
transform(begin(input), end(input), begin(input), ::tolower);
words[input]++;
cout << "Value is now " << words[input] << endl;
cin >> input;
}
//First list sorted alphabetically
//
cout << "\n" << setw(17) << left << "Word" << setw(1) << setw(10) << right << "Frequency" << endl;
cout << setfill('-') << setw(17) << right << " " << setfill(' ') << setw(1) << setfill('-') << setw(10) << left << " " << setfill(' ') << endl;
words.traverse(printMap);
cout << "Traverse completed" << endl;
return 0;
}
//Function that prints the key and value of a node
//
void printMap(const string& key, const int& val){
cout << setw(17) << left << key << setw(1) << setw(10) << right << val << endl;
}
代碼應該輸出按頻率排序的鍵列表,但它到達“到達此處2”行,然后返回分段錯誤。
當你得到分段錯誤時,root可能是一個nullptr。
我可能會遺漏一些東西,但你在構造函數中設置為nullptr,我不知道它在哪里被改變了。
我假設您認為在某些時候將其設置為插入,但您沒有。
即使修復了這個問題---如果你沒有向地圖添加任何東西,它也會崩潰,因為在deleteNotes中你永遠不會檢查nullptr,但你用head作為參數從析構函數中調用它(這將是nullptr )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.