链表C ++ Seg故障

时间:2013-01-29 06:10:37

标签: c++ linked-list

我正在尝试从头创建一个由另一个类使用的简单链接列表。 错误似乎是有时Head未设置为NULL。 我有时会说它不会一直出错。它没有错误的时间,它转到else语句。注意我只添加1个字符串。也许你们可以发现我没看到的东西,干杯!

LinkedList.h:

#include <string>
#include "Link.h"

using namespace std;

class LinkedList {
  Link *head;

public:
  LinkedList();
  void addFront(string key);
  void printList();
  //void addBack(string *);     

};

LinkedList.cpp:

#include <cstring>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include "LinkedList.h"

using namespace std;

LinkedList::LinkedList() {
   head = NULL;
}

void LinkedList::addFront(string key) {
  //creates the new list segment                                                
  Link *l = new Link(key);

  cout << "Made new Link " << key << endl;
  // if the list is empty                                                 
  if (head == NULL){
    cout << "Going to set Head " << key << endl;
    head = l;
    cout << "Set Head to new link " << key << endl;
 }                                            
  else {             
     cout << "Else statement " << key << endl;                  
    l->setNext(head);

    head = l;
  }

}

void LinkedList::printList() {
 //Check if list is empty
  if(head == NULL)
   cout << "NULL" << endl;
  else {
   Link *l = head; 

   for(;l != NULL; l=l->getNext())
     cout << l->getValue() << endl;
  }


}

// void LinkedList::addBack(string *f) {
//   Link *l = new Link(f);

// }

Link.h

#include <cstdlib>
#include <cstring>
#include <string>

using namespace std;

class Link {
string key;
Link *next;

public:
    Link(string key);

    void setValue(char);
    void setNext(Link *next);
    string getValue();
    Link *getNext();
    void printList();

};

Link.cpp

#include <cstdlib>
#include <string>
#include <iostream>
#include "Link.h"

using namespace std;

Link::Link(string key) {
    this->key = key;
next = NULL;

}

void Link::setNext(Link *l) {
cout << "setting new link "<<endl;
next = l;

cout<< "New link was set" << endl;
}

string Link::getValue() {
return key;

}

Link *Link::getNext() {
return next;
}

Hash.h

#include <iostream>
#include <cstring>
#include <string>
#include "LinkedList.h"

using namespace std;

class Hash{
    //100 slot array for hash function
    LinkedList *hashFN[100];

    //preset prime number                                                               
  int prime = 101;
    int key;
  unsigned int location;

public:
    //Note: Both the key & values are the same 
    void insert(string key, string value);
    // void deleteItem(int key);
    // char* find(int key);


};

Hash.cpp:

#include <iostream>
#include <cstring>
#include <string>
#include "Hash.h"

using namespace std;

void Hash::insert(string k, string v){
    //Get Hash for argv[2] aka value                                                  
  size_t key = std::hash<string>()(k);
   unsigned int location;

//check 1                                                                         
  cout << "Hash: " << key << endl;

  //Find location
  location = key % prime;

  //check 2                                                                         
  cout << "Mod 101 Hash: " << location << endl;

    hashFN[location]->addFront(k);
    cout << "Success!" << endl;

}

// void Hash::deleteItem(int key){
//  return;

// }

// char* Hash::find(int key){
//  return;

// }

的main.cpp

#include <iostream>
#include <functional>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include "Hash.h"                                                                   

using namespace std;

int main(int argc, char *argv[]) {

  Hash HashTable;                                                                   


  string Insert = string("insert");
  string Delete = string("delete");
  string Find   = string("find");
  string Argv(argv[2]);  //Makes the argv[2] into string type

  // check for Request & string parameters                                            
  if(argc != 3) {
    cout << "Run program with 2 parameters. [Lower Case]" << endl;
    cout << "[1] insert, find, or delete" << endl;
    cout << "[2] string" << endl;
    exit(1);
  }

  //Check for "insert"                                                                
  if(strcmp(argv[1], "insert") == 0) {


  HashTable.insert(Argv, Argv);                                                

  }

  return 0;
}

1 个答案:

答案 0 :(得分:3)

您的直接问题:哈希表中的链表数组是指针数组。声明为:

LinkedList *hashFN[100];

您似乎永远分配这些对象中的任何一个。所以你只有一个指向100个不确定垃圾指针的指针数组。分配它们,或者更好的是,直接实例化它们:

LinkedList hashFn[100];

这将要求您更改对它们的引用,例如

hashFN[location]->addFront(k);

成为这个:

hashFN[location].addFront(k);

接下来,您使用非const成员变量prime作为散列函数的模数。由于这是硬编码为101,因此您的表格大小必须相同。 (实际上,我完全丢失了成员变量,只是在你的Hash.cpp文件中只是一个静态const)。但除此之外,问题仍然存在。你的桌子是一个太小的插槽。您的模数可以来自0..100,这意味着您需要一个大小为[101]的表来处理所有这些插槽。请记住,C / C ++中的数组[0...(n-1)]针对大小为n

的数组进行寻址

所以至少如此声明你的表:

LinkedList hashFN[101];

我发布的最后一件事。您的链接列表像泰坦尼克号一样泄漏。在销毁列表时,您需要清理所有这些节点。在你的类中声明析构函数:

virtual ~LinkedList();

在你的.cpp文件中实现它:

LinkedList::LinkedList()
{
    while (head)
    {
        Link *victim = head;
        head = head->getNext();
        delete victim;
    }
}

行。我撒了谎。还有一件事,在阅读理解Rule of Three之前,你会感到很舒服,你应该让你的课程不可复制。将以下内容放在LinkedList类声明的私有部分中:

class LinkedList
{
   ... other code...

private:
    LinkedList(const LinkedList&);
    LinkedList& operator =(const LinkedList&);
};

这将隐藏可能导致您主要问题的事情,直到您准备好正确实施它们为止。如果你发现自己有“某些事情的错误”无法访问私人成员LinkedList(const LinkedList&)“那么你正试图制作一份副本,并且没有适当保护你的头部指针那就不行了。< strong>阅读三法则。

其余的我留给你。

注意:有很多方法可以使用标准库(std::vector<>std::unordered_map<>等)轻松完成此操作。事实上,std::unordered_map<>是替代品 所有这些 。但是,如果你只是对使用这种语言感兴趣再次熟悉,那么暂时使用裸机也不错。只需专注于重新学习,然后学会使用标准库提供的所有漂亮代码。