0

リンクされたリストでハッシュテーブルを展開すると、いくつかのエラーと警告があります。次のコードが正しいことを確認し (expand function)、これらの警告/エラーが発生する原因を突き止めたい

編集:私のプロトタイプに警告とエラーが表示されていないことに気付いた@ nosに感謝します。残念ながら、今はこれがあります: "In function expand': undefined reference toadd' collect2: ld returned 1 exit status

EDIT2: add 関数が List* を返すことに気付きました。これは、expand 関数ではそれを「取得」する変数がありません。そこに値を入れました...しかしエラーが残ります:/

EDIT3: セグメンテーション違反 :( gdb で実行中: * glibc が検出されました 破損した二重リンク リスト: 0x0804c6b0 * * 修正済み。新しい追加機能が追加されました。

編集: ルックアップ関数の strcmp でのセグメンテーション違反。gdb で実行:

(gdb) bt フル

0 ルックアップで 0x080487b9 (hashtable=0x804b008、hashval=27、

number=0xbffff3f2 "6900101001") at pro.c:80
    list = 0xffffffff

追加で 1 0x0804883b (hashtable=0x804b008,

number=0xbffff3f2 "6900101001", name=0x804b6e0 "Irgaedggfs",

time=6943) pro.c:96 で new_elem = 0xffffffff hashval = 27

2 メインの 0x08048bc1 (argc=1、argv=0xbffff4b4)、pro.c:234

    number = "6900101001"
    name = 0x804b6e0 "Irgaedggfs"
    time = 6943
typedef struct 
{
     int length;        
     struct  List *head;    
} HashTable;

  //resolving collisions using linked lists - chaining
typedef struct 
{
     char *number;
     char *name;
     int time;
     struct List *next;
}List;



HashTable* expand( HashTable* h )
{    
          HashTable* new;
          int n;
          List *node,*next;
          PrimesIndex++;
          int new_size= primes[PrimesIndex];        /* double the size,odd length */

          if (!(new=malloc((sizeof( List*))*new_size))) return NULL;

          for(n=0; n< h->length; ++n) {
                for(node=h[n].head; node; node=next) {
                      add (new, node->number, node->name,node->time);
                      next=node->next;
                      free(node);
                }
          }
          free(h);
          return new;
}


int add ( HashTable* hashtable,char number[10],char* name,int time)
{
     List *new_elem;
    int hashval=hash (hashtable,number);

    new_elem=hashtable[hashval].head;
    if(hashtable[hashval].length>0) 
    {                   
          if ((lookup (hashtable,hashval,number))!=NULL) {return 0;}    
    }

    if (!(new_elem=malloc(sizeof(struct  List)))){ return -1;}

    //insert values for the new elem
    new_elem->number=strdup(number);    
    new_elem->name=strdup(name);
    new_elem->time=time;

    hashtable[hashval].head=new_elem;
    new_elem->next=NULL;
    hashtable[hashval].length++;

    /* rehash existing entries if necessary */
    if( TableSize(hashtable)>= 2*size]) 
    {    
         hashtable = expand(hashtable);
         if (hashtable ==NULL){
           return 0;
         }

    }
    return 1;
}



List *lookup ( HashTable *h ,int hashval,char number[10])
{
    List *list=h[hashval].head;
    for(list; list!=NULL; list=list->next){
            if (strcmp(number,list->number)==0)  //**SEGMENTATION**!!!!
                return list;

    }
    return NULL;
}
4

3 に答える 3

1

関数を呼び出す前に関数を宣言する必要があります。それ以外の場合、C は、とりわけ、expand関数が int を返すと想定します。

単純に、このようなプロトタイプをファイルの先頭、構造体宣言の後、関数定義の前に配置します。

 HashTable* expand( HashTable* h ,char number[10],char* name,int time);
于 2011-01-16T00:02:34.040 に答える
0

「add」を使用する「expand」を定義する前に、関数「add」を宣言します。

List* add ( HashTable* hashtable,char number[10],char* name,int time);

ここで展開を定義..

定義 ここに追加...

于 2011-01-16T01:44:57.683 に答える
0

(コンピューターで行を変更する方法がわからないため、コメントに従うのではなく、新しい回答を投稿する必要があります。申し訳ありません)

試してください:

int add ( HashTable** phashtable,char number[10],char* name,int time){

...

if(hashTableSize( *phashtable)== 2*(primes[PrimesIndex])){ 
     *phashtable = expand( *phashtable);
}

}

それに応じて、「追加」と「追加」の呼び出しを変更する必要がある場合があります。

これが役立つかどうかはわかりません。少なくともこれはバグの 1 つです。

バグは、Hashtable が add 呼び出しで展開された場合、add 呼び出しが戻った後、変数「hashtable」の値が変更されないことです。

于 2011-01-16T03:16:23.367 に答える