错误 - "在抛出' std :: logic_error' ..."的实例后终止调用在实例化抽象类时

时间:2016-12-06 06:27:57

标签: c++

我试图完成一个我们实现哈希表的赋值。我已经使用链接的节点列表来执行此操作。我的Hash类是纯虚拟类,因为它的hash函数是纯虚函数。 Hash类也是模板类。

我已经成功地实现了该类的int和float版本。但是当我尝试实现一个字符串版本并实例化一个对象时,它给了我这个错误:

  

在抛出' std :: logic_error'的实例后终止调用     what():basic_string :: _ S_construct null无效

根据我的阅读,这与使用std::string实例化NULL对象有关。我只是没有看到我这样做的地方。

我提前为我的代码有点混乱而道歉,并感谢愿意提供帮助的任何人!

/******************************************************************
 * Class: 
 *      Hash
 * Summary:
 *      This is a class for a abstract "hash" data type.
 *****************************************************************/
#ifndef HASH_H
#define HASH_H

#include <iomanip>
#include <iostream>
#include <string>
#include "node.h"



template <class T>
class Hash
{
   //private:
  public:
   node <T> * table;  // hash table
   int numList;       // number of items in hash table
   int numItems;      // number of lists in the hash table

  public:

   // non-default constructor
   Hash(int numBuckets) throw (const char *)
   {
       try
       {
          table = new node<T>[numBuckets];
          for (int i = 0; i < numBuckets; i++)
          {
             table[i].setValue(T());
          }
          this->numList = numBuckets;
          this->numItems = 0;
       }
       catch (std::bad_alloc)
       {
          this->numList = 0;
          this->numItems = 0;
          for (int i = 0; i < numBuckets; i++)
             this->table[i] = node<T>();          
          throw "ERROR: Unable to allocate memory for the hash.";
       }
   }

   // destructor
   ~Hash() { clear(); };

   // pure virtual function hash function
   virtual int hash(const T & t)const = 0;

   // return capacity
   int capacity() const { return numList; }

   // is table empty?
   bool empty() const { return numItems == 0; }

   //display       
   void display()
   {
      for(int i = 0; i < numList; i++)
      {
         std::cout << std::setw(10) << i
                   << " : " << table[i].size() << std::endl;
      }
   }

   // return numItems
   int size() const { return numItems; }

   // copy constructor
   Hash(const Hash <T>& rhs) throw (const char *) : table(NULL), numItems(0), numList(0)
   {
      *this = rhs;
   }

   // clear the dynamically allocated memory
   void clear();

   // assignment operator
   Hash <T> & operator = (const Hash <T> & rhs) throw (const char *);

   //find - return true if found, false if else.
   bool find(const T & t) const;

   // insert
   void insert(const T & t);

};


//insert

template <class T>
void Hash <T> :: insert(const T & t)
{
   int hashKey = hash(t);

   node <T> * newEntry = new node<T>(hashKey, t);

   //check initial hashKey slot
   if (table[hashKey].getValue() == T())
   {
      table[hashKey] = newEntry;
      numItems++;

      return;
   }
   else
   {
//      hashKey++;
      for (int i = 0; i < numList; i++)
      {  // check the remaining nodes
         if (table[hashKey].getValue() == T())
         {
            table[hashKey] = newEntry;
            numItems++;
            return;
         }
         hashKey = (hashKey + 1) % capacity();

      }

      hashKey = hash(t);  // reset hashKey
      if (table[hashKey].pNext != NULL)
      {
         node <T> * ptr = &table[hashKey];
         for (ptr; ptr->pNext != NULL; ptr = ptr->pNext) {};
         if (ptr->pNext == NULL)
         {
            ptr->pNext = newEntry;
            numItems++;

            return;
         }
      }
      else if (table[hashKey].pNext == NULL)
      {
         table[hashKey].pNext = newEntry;
         numItems++;
      }
   }

}

// find - return true if found, false if else.
template <class T>
bool Hash <T> :: find(const T & t) const
{
   int hashKey = hash(t);

   for (int i = 0; i < numList; i++)
   {
      if (table[hashKey].getValue() == t)
         return true;
      node <T> * ptr = &table[hashKey];
      if (ptr->getValue() == t)
         return true;

      while (ptr != NULL)
      {
         if (ptr->getValue() == t)
            return true;
         ptr = ptr->pNext;
      }
      hashKey = (hashKey + 1) % capacity();
   }
   return false;

}


// clear the hash table
template <class T>
void Hash <T> :: clear()
{
   delete [] table;
}

// assignment operator
template <class T>
Hash <T> & Hash<T> :: operator =(const Hash <T> & rhs) throw (const char *)
{
   // allocate if necessary
   if (rhs.numList != numList)
   {
      try
      {
         node <T> * tableNew = new node <T> [rhs.numList];
         delete [] table;
         numList = rhs.numList;
         table = tableNew;
      }      
      catch (std::bad_alloc)
      {
         throw "ERROR: Unable to allocate memory for the hash";
      }
   }
   // copy the data
   for (int i = 0; i < numList; i++)
      table[i] = rhs.table[i];
   numItems = rhs.numItems;

   // return this
   return *this;
}



#endif // HASH_H

和node.h

#ifndef NODE_H
#define NODE_H

#include <cassert>
#include <iostream>




    template <class T>
    class node
    {
      private:
       int key;
       T value;


      public:

       node * pNext;

       // default constructor
      node() : key(0), value(0), pNext(NULL) {};

       // non-default constructor
      node(int pKey, T pVal) : key(pKey), value(pVal), pNext(NULL) {};

       // set value
       void setValue(T  value)
       {
          this->value = value;
       }

       // key - getter
       int getKey()
       {
          return key;
       }

       // value - getter
       T  getValue()
       {
          return value;
       }

       node * getNext()
       {
          return pNext;
       }

       void setNext(node * newNext)
       {
          this->pNext = newNext;
       }

       void setNext(node & newNext)
       {
          pNext = newNext;
       }

       bool checkNode()
       {
          if (this->pNext == NULL)
             return true;
          else
             return false;
       }

       void setNULL()
       {
          this = NULL;
       }

       node<T> operator=(node<T> * rhs)
       {
          this->key = rhs->key;
          this->value = rhs->value;
          this->pNext = rhs->pNext;
       }


    };
    #endif //NODE_H

和spellCheck.cpp - 实现Hash类。

/***********************************************************************
 * Module:
 *    Week 12, Spell Check
 *  
 * Author:
 *  
 * Summary:
 *    This program will implement the spellCheck() function
 ************************************************************************/

#include <iostream>
#include <fstream>
#include <string>
#include "spellCheck.h"
#include "hash.h"
#include <fstream>

using namespace std;

/******************************************************
 * Class: SHash
 * Author: 
 * Summary: A derived hash table for strings
 *****************************************************/
class SHash : public Hash <string>
{
public:
   SHash(const int numBuckets) throw (const char *) : Hash <string> (numBuckets) {}

   SHash(const SHash & rhs) throw (const char *) : Hash <string> (rhs)  {}

   //hash function for strings
   int hash(const string & s) const
   {
      int hashValue = 0;
      for (int i = 0; i < s.length(); ++i)
      {
         char c = s[i];
         hashValue = (hashValue + c);
      }
      return hashValue;
   }

};


/*****************************************
 * SPELL CHECK
 * Prompt the user for a file to spell-check
 ****************************************/
void spellCheck()
{
   SHash dictionary(101);

};

0 个答案:

没有答案