繁体   English   中英

自定义地图类中的分段错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM