連鎖配列ハッシュ テーブルからアイテムを取得しようとしています。検索関数は、ハッシュ テーブルがメンバーであるクラス テーブルに属します。テーブルは client クラスのメンバーです。これはクラス用であるため、使用できるものは非常に限られています (たとえば、文字列はなく、文字の配列のみ)。クライアントからのアイテムの配列と、ハッシュ キーを生成するアイテムの名前または特性を渡したいと考えています。
... 検索関数を呼び出す main の一部 (渡された int は、名前または効果で検索している天気を決定するフラグです)
program.reference.retrieve("Abecean Longfin", program.client_item, 1);
cout << program.client_list[0].name;
getchar();
return 0;
}
....
item.h
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
const int ASIZE = 30;
const int SIZE = 92;
const int HNSIZE = 41;
const int HESIZE = 17;
struct item
{
item();
~item();
char * name;
char * effect1;
char * effect2;
char * effect3;
char * effect4;
int count;
//int keygen(int,int);
/*int name_key;
int ef1_key;
int ef2_key;
int ef3_key;
int ef4_key;*/
};
.... 検索機能
int table::retrieve(char item_in[],item*item_list, int name_flag)
{
int i = 0;
if(name_flag)
{
node * temp;
int key = keygen(item_in,HNSIZE);
if(!(name_table.ht[key]))
return 0;
else
temp = name_table.ht[key];
while(temp)
{
if(!strcmp(item_in,temp->ingredient->name))
item_list[i] = *temp->ingredient;
++i;
temp = temp->next;
}
}
else
{
node * temp;
int key = keygen(item_in,HESIZE);
if(!(ef1_table.ht[key]) && !(ef2_table.ht[key]) && !(ef3_table.ht[key]) && !(ef4_table.ht[key]))
return 0;
else
{
temp = ef1_table.ht[key];
while(temp)
{
if(!strcmp(item_in,temp->ingredient->effect1))
item_list[i] = *temp->ingredient;
++i;
temp = temp->next;
}
temp = ef2_table.ht[key];
while(temp)
{
if(!strcmp(item_in,temp->ingredient->effect2))
item_list[i] = *temp->ingredient;
++i;
temp = temp->next;
}
temp = ef3_table.ht[key];
while(temp)
{
if(!strcmp(item_in,temp->ingredient->effect3))
item_list[i] = *temp->ingredient;
++i;
temp = temp->next;
}
temp = ef4_table.ht[key];
while(temp)
{
if(!strcmp(item_in,temp->ingredient->effect4))
item_list[i] = *temp->ingredient;
++i;
temp = temp->next;
}
}
}
}
....
client.h
#include "table.h"
struct client
{
client();
int fill_list(int,int,int);
int copy(char*,char*,int);
int display(char*, int, item*);
item * client_list;
table reference;
table inventory;
item client_item;
};
....
table.h
#include "hash.h"
class table
{
public:
table();
~table();
int fill(item*);
int insert(item&, nHash&);
int insert(item&, eHash&, int);
int retrieve(char*,item*,int);
int remove(int,item&);
int remove(int);
int check_hash(int,int,int);
int keygen(char*, int);
int from_list(int, item&);
int into_list(int, item&);
item* get_list();
private:
item * item_list;
nHash name_table;
eHash ef1_table;
eHash ef2_table;
eHash ef3_table;
eHash ef4_table;
};
....
キー生成関数
int table::keygen(char*input, int hash_size)
{
if(input)
{
int key = 0;
int i = 0;
while(input[i])
{
key = key + input[i] * 101 * input[i++];
}
return key%hash_size;
}
else
return -1;
}
.... client_item init を追加しました
client::client()
{
client_item.name = new char[ASIZE];
client_item.effect1 = new char[ASIZE];
client_item.effect2 = new char[ASIZE];
client_item.effect3 = new char[ASIZE];
client_item.effect4 = new char[ASIZE];
client_list = NULL;
}
私が含める必要がある他のものがあると確信しています。しかし、これでうまくいくと思います。私はまだプログラミングと C++ の初心者です。
私が抱えている問題は、名前を計算しようとしたときに NULL ポインターを逆参照することです。少なくとも、それが「アクセス違反の読み取り場所0x00000000」であると思います。