2012-04-11 12 views
0

リンクリストチェーンを使用してハッシュテーブルを実装しようとしています。以下のコードは動作します -ハッシュテーブルリンクリスト - セグメント化エラー

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define TABSIZ 200 

struct record { 
    struct record *next; 
    char name[BUFSIZ]; 
    int data; 
}; 

static struct record *htable[TABSIZ]; 

unsigned hash(char *s) 
{ 
    unsigned h; 

    for (h = 0; *s; s++) 
     h = *s; 
//printf("%d", h%TABSIZ); 
//I know its not a good hash function but i wanted to check chaining 
    return h % TABSIZ; 
} 

struct record *find(char *name) 
{ 
    struct record *item; 

    for (item = htable[hash(name)]; item; item = item->next) 
    { 
     if (strcmp(name, item->name) == 0) 
      return item; 
    } 

    return NULL; 
} 

struct record *insert(char *name,int value) 
{ 
    struct record *item; 
    unsigned h; 

    if ((item = find(name)) == NULL) 
    { 
     if ((item = malloc(sizeof (*item))) == NULL) 
      return NULL; 

     strcpy(item->name, name); 
     item->data=value; 
     h = hash(name); 
     item->next = htable[h]; 
     htable[h] = item; 
    } 

    return item; 
} 
void printTable() 
{ 
    int i=0; 
    struct record *temp; 
    for(i=0;i<=TABSIZ;i++) 
    { 
     temp=htable[i]; 
     while(temp!=NULL) 
     { 
      printf("\n%d - %s - %d\n", i,temp->name, temp->data); 
      temp=temp->next; 
      } 
    } 
} 
int main(void) 
{ 
    char buf[BUFSIZ];int value; 
    struct record *item; 
    do{ 
    printf("Enter the name of the student:\n"); 
    scanf("%s", buf); 
    if(strcmp(buf,"stop")==0) break; 
    printf("Enter the marks of the student:\n"); 
    scanf("%d", &value); 
    if(insert(buf, value)==NULL) 
    { 
     break; 
    } 
}while((strcmp(buf,"stop"))!=0); 

    printf("Enter a name to find: "); 
    scanf("%s", buf); 
    if((item=find(buf))!=NULL) 
     printf("The marks of the student is %d\n", item->data); 
    else printf("\n Not Found\n"); 
    printTable(); 
    return 0; 
} 

グローバル変数を削除し、構造体の配列にローカル変数を使用しようとしています。私はhtableのグローバル宣言を取り除き、

struct record *htable[TABSIZ]; 

としてメインでそれを宣言し、

struct record *find(struct record *htable, char *name); 
struct record *insert(struct record *htable, char *name,int value); 

に機能を変更し、私は

find(htable, name); 
insert(htable,name,value); 

としての機能を呼び出すことが、今、私のよプログラムはsegfaultingです。構造体の配列を正しく渡していますか?私はそれを正しく宣言しました。どんな助けでも大歓迎です。 printTableで

+1

「検索」と「挿入」に渡す「名前」とは何ですか?それはまだBUF [BUFSIZ]サイズの配列、多分どこセグメンテーション違反がから来ている... は最初の要素へのポインタを渡してみている場合:&htable [0] 私はあなたの配列の宣言がcoorectだと思いますこれはヒープではなくスタック上の何かにポインタを渡しているので問題のポイントになる可能性があります(ただし、メインから戻った場合のみです)。 –

答えて

2

私は以前の答えで間違った道を下っていた。

それはグローバルだとき、それがメインのスタック上で宣言だとき、それは自動的に0

に初期化されます、それが初期化されていません。

memset(htable, 0, sizeof(htable))main()に追加すると、以前の動作に戻ります。

+1

良いキャッチ! OPに:なぜ "作品"のコードを投稿し、本当の "嫌な"編集をテキストに入れますか? (私はテキストだけでなく、ソースを読む) – wildplasser

0

():

for(i=0;i<=TABSIZ;i++) 

は、容疑者を探します。あなたはほしいと思う:

void printTable() 
{ 
    unsigned int i; 
    struct record *temp; 

    for(i=0; i < TABSIZ;i++) 
    { 
     for (temp=htable[i]; temp!=NULL; temp=temp->next) 
     { 
      printf("\n%d - %s - %d\n", i,temp->name, temp->data); 

     } 
    } 
} 
関連する問題