3

別のクラスで使用される単純なリンク リストをゼロから作成しようとしています。エラーは、Head が NULL に設定されていない場合があるようです。私は時々、それが常にセグメント化されていない前に言います。seg fault でないときは、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();

};

リンク.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);


};

ハッシュ.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;
}
4

1 に答える 1

3

当面の問題: ハッシュ テーブル内のリンク リスト配列はポインタ配列です。次のように宣言されています。

LinkedList *hashFN[100];

これらのオブジェクトを割り当てないようです。したがって、ガベージへの 100 個の不確定ポインターのポインター配列しかありません。それらを割り当てるか、さらに良いのは、それらを直接インスタンス化することです。

LinkedList hashFn[100];

これには、それらへの参照を次のように変更する必要があります。

hashFN[location]->addFront(k);

これになります:

hashFN[location].addFront(k);

prime次に、ハッシュ関数のモジュラスとして非 const メンバー変数を使用しています。これは にハードコードされているため101、テーブルは同じサイズである必要があります。(そして実際には、メンバー変数を完全に失い、Hash.cpp ファイルの static const だけを失うことになります)。しかし、それとは別に、問題はまだ残っています。あなたのテーブルは 1 スロット小さすぎます。あなたのモジュロはからである可能性があります。つまり、これらすべてのスロットに対応するサイズ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;
    }
}

わかった。私は嘘をついた。もう 1 つ、 Rule of Threeを読ん理解できるようになるまでは、クラスをコピー不可にする必要があります。LinkedList クラス宣言のプライベート セクションに次のコードを追加します。

class LinkedList
{
   ... other code...

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

これにより、適切に実装する準備が整うまで、大きな問題を引き起こす可能性のあるものを隠すことができます。「プライベート メンバーにアクセスできない」というエラーが発生した場合LinkedList(const LinkedList&)は、コピーを作成しようとしており、ヘッド ヘッド ポインターを適切に保護していないため、3 のルールをお読みください

残りはあなたに任せます。

std::vector<>注: 標準ライブラリ ( 、std::unordered_map<>など)を使用すると、これをより簡単に行う方法がたくさんあります。実際、std::unordered_map<>は、このすべての. しかし、その言語に再び慣れるために作業することに興味があるだけなら、しばらくベアメタルに取りかかるのも悪くありません。再学習に集中して、標準ライブラリが提供する美しいコードをすべて使用することを学びましょう。

于 2013-01-29T06:43:40.883 に答える