2011-02-04 60 views
0

時,我有類型的結構:Ç分段故障加入散列節點

struct hashnode_s { 
    struct hashnode_s *next; 
    char *key; 
    ValueType tag; 
    union 
    { 
     int IntegerValue; 
     char *StringValue; 
    } u; 
    int IsInCycle; 
}; 

當我添加String類型的項目,我可以,它的代碼是

int hashtbl_InsertString(HASHTBL *hashtbl, const char *key, const char *value) 
{ 
    struct hashnode_s *node; 
    hash_size hash; 

    hash = SearchForHashIndex(hashtbl, key,value); 

    if(hash == -1) 
    { 
     hash=hashtbl->hashfunc(key); 
    } 
    /* adding the first node if not applicable (this is based on value string)*/ 

    if(hashtbl->nodes[hash]== NULL) 
    { 
     node = malloc(sizeof(struct hashnode_s)); 
     node->key = key; 
     node->tag = StringConst; 
     node->u.StringValue = value; 
     node->next = NULL; 
     hashtbl->nodes[hash] = node; 
    } 
    else 
    { 
     node = hashtbl->nodes[hash]; 

     if(node->next ==NULL) 
     { 
      struct hashnode_s *nextNode; 
      nextNode = malloc(sizeof(struct hashnode_s)); 

      if(strcmp(node->u.StringValue,key)==0) 
      { 
       /* set next */ 
       nextNode->key = key; 
       nextNode->tag = StringConst; 
       nextNode->u.StringValue = value; 
       nextNode->next = NULL; 
       node->next = nextNode; 
       hashtbl->nodes[hash] = node; 
      } 
      else if(strcmp(node->key, value)==0) 
      { 
       /* switch node positions if the key */ 
       nextNode->key = key; 
       nextNode->tag = StringConst; 
       nextNode->u.StringValue = value; 
       node->next = NULL; 
       nextNode->next = node; 
       node = nextNode; 
       hashtbl->nodes[hash] = nextNode; 
      } 
     } 
     else 
     { 
      while(node) 
      { 
       struct hashnode_s *nextNode; 
       nextNode = malloc(sizeof(struct hashnode_s)); 

       /* TESTING PURPOSES ONLY 
       printf("#define %s %s\n",node->key,node->u.StringValue); 
       printf("%s==%s\n",node->u.StringValue,key); 
       printf("%s==%s\n\n\n",node->key, value); 
       */ 

       if(strcmp(node->u.StringValue,key)==0) 
       { 
        nextNode->key = key; 
        nextNode->tag = StringConst; 
        nextNode->u.StringValue = value; 
        nextNode->next = NULL; 
        node->next = nextNode; 
        return 0; 
       } 
       else if(strcmp(node->key, value)==0) 
       { 
        nextNode->key = key; 
        nextNode->tag = StringConst; 
        nextNode->u.StringValue = value; 
        node->next = NULL; 
        nextNode->next = node; 
        node = nextNode; 
        return 0; 
       } 
       node = node->next; 
      } 
     } 
    } 
} 

但是,當我添加一個整數類型的項目。它出於某種原因引發了分段錯誤?

這是代碼。

int hashtbl_InsertValue(HASHTBL *hashtbl, const char *key, int integerValue) 
{ 
    struct hashnode_s *node; 
    hash_size hash; 

    hash = SearchByKey(hashtbl, key); 
    if(hash == -1) 
    { 
     hash=hashtbl->hashfunc(key); 
    } 

    if(hashtbl->nodes[hash] ==NULL) 
    { 
     node = malloc(sizeof(struct hashnode_s)); 
     node->key = key; 
     node->tag = IntegerConst; 
     node->u.IntegerValue = integerValue; 
     node->next = NULL; 
     hashtbl->nodes[hash] = node; 
     return 0; 
    } 
    else 
    { 
     node = hashtbl->nodes[hash]; 
     //Check(hashtbl); 
     while(node) 
     { 
      if(strcmp(node->u.StringValue,key)==0) 
      { 
       struct hashnode_s *nextNode; 
       nextNode = malloc(sizeof(struct hashnode_s)); 

       nextNode->key = key; 
       nextNode->tag = IntegerConst; 

       nextNode->u.IntegerValue = 5; 
       nextNode->next = NULL; 

       if(node->next == NULL) 
       { 
        // THIS IS WHERE IT CRASHES AT! 
        node->next = nextNode; 
       } 

       return 0; 
      } 
      node=node->next; 
     } 
    } 
} 

我試圖擺脫分段故障,但我不能有任何想法?

+0

area node-> next = next node是什麼引發了分段錯誤。這真的很煩人。我無法完成沒有通過這個! – Kevin 2011-02-05 00:01:23

回答

0

一些緊迫的問題看你的代碼時,映入了我的注意:

  1. 你總是做的strcmp用的StringValue即使它與IntegerValue工會,這意味着STRCMP將讀取一個無效的內存地址並導致整數值的段錯誤。
  2. 您的散列表是否已初始化?如果不是,則聲明的代碼行很可能是段錯誤,因爲這是第一次在沒有寫入權限的頁面上進行寫入操作。
  3. 在將分配的節點分配給下一個節點之前,檢查下一個節點是否爲NULL,如果失敗則不釋放內存,則此內存泄漏可能是個問題。對於數字1的明顯解決方案是,將下一個指針指向NULL作爲已到達列表末尾的指示符,而不是檢查可能不總是存在的字符串。
  4. 散列是一個有符號整數,確保從散列函數返回的唯一負數是-1,因爲任何其他否定都可能很容易成爲另一個超出界限的訪問錯誤。

如果我是你,那麼在試圖追蹤這個錯誤之前,我會解決這些其他問題,當你只是在尋找一個錯誤時更容易發現錯誤。