2011-02-04 62 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,因为任何其他否定都可能很容易成为另一个超出界限的访问错误。

如果我是你,那么在试图追踪这个错误之前,我会解决这些其他问题,当你只是在寻找一个错误时更容易发现错误。