2011-02-04 15 views
0

を追加する場合:Cセグメンテーション障害Iタイプの構造を有するハッシュノード

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

およびIは、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

領域node-> next =次のノードがセグメンテーションフォールトをスローします。これは本当に面倒です。私はこれを過ぎて終えることができない! – Kevin

+0

デバッガを使用して、クラッシュがどこにあるかを確認します。たとえば、プログラムが失敗した後のgdbタイプのバックトレース。 – Alexandru

+0

'if(strcmp(node-> u.StringValue、key)== 0)'もしあなたがノードにIntegerを格納したら? u.StringValueは、いくつかの偽のアドレスを指す必要があります。私の推測では、あなたは 'union'が何をしているのか誤解しています。あなたの場合、整数とポインタは同じデータを共有し、意図した整数とキーは共有しません。ユニオンをそのままにしておきます(この最適化の必要はありません)。 – Alexandru

答えて

0

あなたのコードを見たときに、いくつかの即時の問題は私の注意に春:

  1. あなたはいつもするIntegerValueとの連合で、これはstrcmpのが無効なメモリを読み取ることを意味しているにもかかわらず、STRINGVALUEとのstrcmpを行います整数値のセグメンテーションを引き起こします。
  2. ハッシュテーブルは初期化されていますか?そうでなければ、書込みアクセスのないページで初めて書込みが行われるため、主張して​​いるコード行がセグメンテーションしている可能性があります。
  3. 割り当てられたノードを次のノードに割り当てる前に次のノードがNULLかどうかを確認し、失敗した場合はメモリを解放せずにこのメモリが漏れてしまう可能性があります。番号1の明白な解決策は、常にそこにあるとは限らない文字列をチェックするのではなく、リストの終わりに達したというインジケータとしてNULLの次のポインタを使用することです。
  4. ハッシュは符号付き整数で、ハッシュ関数から返された唯一の負の数が-1であることを保証します。

私があなただったら、このエラーを追跡する前にこれらの他の問題を修正すると、エラーを見つけようとするときにエラーを見つけやすくなります。