Развернуть цепочку хеш-таблицы.Ошибки в коде. [ОБНОВЛЕНО - Новый вопрос] - PullRequest
0 голосов
/ 16 января 2011

Расширение хеш-таблицы со связанными списками, есть некоторые ошибки и предупреждения.Я хочу убедиться, что следующий код правильный (функция расширения) и выяснить, что происходит, что вызывает эти предупреждения / ошибки

РЕДАКТИРОВАТЬ: Благодаря @ nos , которые заметили, что мой прототип отсутствуетпредупреждения + ошибки, на которые я ссылался, исчезли.К сожалению, теперь есть такой: "В функции expand': undefined reference to add 'collect2: ld вернул 1 состояние выхода

EDIT2: я заметил, что функция add возвращает обратно List *, который при расширении функциинет никакой переменной, чтобы "получить" его. Я поместил значение туда ... но ошибка остается: /

EDIT3: Ошибка сегментации :( Запуск с gdb: * Обнаружен glibc поврежденный двойной связанный список: 0x0804c6b0 ** ИСПРАВЛЕНО. НОВАЯ ДОБАВЛЕННАЯ ФУНКЦИЯ ДОБАВЛЕНА.

РЕДАКТИРОВАТЬ : Ошибка сегментации в strcmp при функции поиска. Работает с gdb:

(gdb) bt full

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",

время = 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;
}

Ответы [ 3 ]

1 голос
/ 16 января 2011

Вам нужно объявить функции, прежде чем вызывать их.В противном случае C, среди прочего, предположит, что ваша expand функция возвращает int.

Просто поместите prototype , как этот, вверху вашего файла, после ваших объявлений структуры,перед вашими определениями функций.

 HashTable* expand( HashTable* h ,char number[10],char* name,int time);
0 голосов
/ 16 января 2011

(я не знаю, как изменить строки в компьютере; поэтому я должен опубликовать новый ответ, а не следовать вашему комментарию. Извините)

Пожалуйста, попробуйте:

int add(HashTable ** phashtable, номер символа [10], char * name, int time) {

...

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

}

вам может понадобиться изменить «add» и вызвать «add»"соответственно.

Я не уверен, поможет ли это.По крайней мере, это одна из ошибок.

Ошибка заключается в том, что если Hashtable раскрывается в вызове add, то после возврата вызова add значение переменной hashtable не изменится.

0 голосов
/ 16 января 2011

объявите функцию «добавить», прежде чем определить «развернуть», в которой вы используете «добавить».

Список * add (HashTable * hashtable, номер символа [10], имя char *, int time);

определить, развернуть здесь ..

определить добавить сюда ...

...