2012-04-11 118 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。我是否正確地傳遞了結構數組?並且我宣佈它是正確的。任何幫助將不勝感激。

+1

什麼是您傳遞給「查找」和「插入」的「名稱」?如果它仍然是buf [BUFSIZ]大小數組,那麼這可能是段錯誤來自... 嘗試傳遞一個指針指向第一個元素:&htable [0] 我認爲你的數組聲明是coorect ,這可能是一個問題點,因爲你傳遞了一個指向堆棧上的東西的指針,而不是在堆中(但只有當你已經返回主線程時,情況並非如此) – 2012-04-11 21:39:31

回答

2

我以前的答案走錯了路。

當它是一個全球性的,它會自動初始化爲0

當宣佈主要在堆棧上年代,它未初始化。

main()中添加memset(htable, 0, sizeof(htable)),並且應該將其返回到先前的行爲。

+1

好抓住!對於OP:爲什麼你張貼代碼「有效」,並將真正的「違規」編輯置於文本中? (我只讀過來源,而不是文字) – wildplasser 2012-04-11 21:33:34

0

在printTable():

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); 

     } 
    } 
}