2016-11-21 8 views
-4

Мы пытаемся настроить хеш-таблицу и некоторые процедуры, которые будут устанавливать, получать и удалять значения из таблицы. Мы встретив «условный переход или шаг зависит от неиницализированных значений (s)» проблема на линии 35 и 53.Хэш-таблица «Неинициализированное значение было создано путем распределения стека»

==23720== Conditional jump or move depends on uninitialised value(s) 
==23720== at 0x400CF6: hash (hashserver.c:35) 
==23720== by 0x400D49: set (hashserver.c:53) 
==23720== Uninitialised value was created by a stack allocation 
==23720== at 0x40112A: main (hashserver.c:133) 

В случае, если есть коллизия в хэше-таблице, мы используем отдельные цепочки с связаны список. Не могли бы вы помочь? Благодаря!

typedef struct KeyVal { 
    unsigned char* value; 
    unsigned char* key; 
    struct KeyVal* next; 
}KeyVal; 

unsigned long hash (unsigned char *str) 
{ 
    unsigned long hash = 5381; 
    int c; 

    (line 35) -> while (c = *str++) 
    hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ 

    return hash%MAXHASHTABLEN; 
} 

int set(KeyVal *hashtable[], unsigned char* key, unsigned char* value){ 
(line 53)-> unsigned long hval = hash(key); 

    if(hashtable[hval] == NULL){ 
     KeyVal* runvar = calloc(1, sizeof(KeyVal)); 
     runvar->key = key; 
     runvar->value = value; 
     runvar->next = NULL; 
     hashtable[hval] = runvar; 
     fprintf(stdout, "Successful set 1\n"); 
     return 1; 
    } else { 
    KeyVal* counter = hashtable[hval]; 
    KeyVal* prev = counter; 
    while(counter!= NULL){ 
     prev = counter; 
     counter = counter->next; 
    } 
     KeyVal* runvar = calloc(1, sizeof(KeyVal)); 
     runvar->key = key; 
     runvar->value = value; 
     runvar->next = NULL; 
     prev->next = runvar; 
     fprintf(stdout, "Successful set 2\n"); 
     return 2; 
    } 
    return -1; 
} 

(line 133) -> int main(int argc, char *argv[]){ 
    int sock, new, status, command; 
    struct addrinfo hints, *serverinfo, *p; 
    struct sockaddr_storage their_addr; 
    socklen_t sin_size; 
    int yes = 1; 
    char s[INET6_ADDRSTRLEN]; 
    unsigned int numbytes = 0; 
    char buffer[128]; 
    int line, transid, bitcounter = 0; 
    unsigned short keylenMSB, keylenLSB, keylen, vallenMSB, vallenLSB, vallen = 0; 
    KeyVal *hashtable[MAXHASHTABLEN]; 
} 

Это упражнение с использованием RPC, и мы получаем команду от клиента таким образом. В самом конце мы называем функцию множества():

unsigned char keybuf[MAXBUFFERLEN], valbuf[MAXBUFFERLEN] = {0}; 

while(1) { 
    sin_size =(socklen_t) sizeof(their_addr); 
    new = accept(sock, (struct sockaddr *)&their_addr, &sin_size); 
    if (new == -1) { 
     perror("accept"); 
     continue; 
    } 

    inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); 
    printf("server: got connection from %s\n", s); 

     if((numbytes = recv(new, buffer, sizeof(buffer), 0)) < 0){ 
      perror("recv"); 
      exit(1); 
     } 
     printf("%d\n", numbytes); 

     for(line = 0; line < numbytes; ++line){ 
      printf("Byte#%d = ",line); 
      for(bitcounter = 0; bitcounter < 8; bitcounter++){ 
       printf("%d ", (buffer[line] >> bitcounter)&1); 
      } 
      printf("\n"); 
      switch(line){ 
       case 0: switch(buffer[line]) { 
          case 1: command = (buffer[line]); fprintf(stdout, "line = %d, command = %d\n", line, command); /*D*/ break; 
          case 2: command = (buffer[line]); fprintf(stdout, "line = %d, command = %d\n", line, command); /*S*/ break; 
          case 3: command = (buffer[line]); fprintf(stdout, "line = %d, command = %d\n", line, command); /*SD*/ break; 
          case 4: command = (buffer[line]); fprintf(stdout, "line = %d, command = %d\n", line, command); /*G*/ break; 
          case 5: command = (buffer[line]); fprintf(stdout, "line = %d, command = %d\n", line, command); /*GD*/ break; 
          case 6: command = (buffer[line]); fprintf(stdout, "line = %d, command = %d\n", line, command); /*SG*/ break; 
          case 7: command = (buffer[line]); fprintf(stdout, "line = %d, command = %d\n", line, command); /*SGD*/ break; 
          default: fprintf(stdout,"Not a valid command\n"); /*Fehlermeldung*/ break; 
       } 
       case 1: transid = buffer[line]; break; 
       case 2: keylenMSB = buffer[line]; keylenMSB = keylenMSB << 8; break; 
       case 3: keylenLSB = buffer[line]; keylen = keylenMSB|keylenLSB; ; break; 
       case 4: vallenMSB = buffer[line]; vallenMSB = vallenMSB << 8; break; 
       case 5: vallenLSB = buffer[line]; vallen = vallenMSB|vallenLSB; break; 
       default: if(line < numbytes - vallen){ 
         keybuf[line - 6] = buffer[line]; 
       } else if(vallen > 0){ 
         valbuf[line-6-keylen] = buffer[line];  
       } 
      } 
     } 

     switch(command){ 
      case 1: delete(hashtable, keybuf); /*D*/ break; 
      case 2: set(hashtable, keybuf, valbuf); /*S*/ break; 
      case 4: get(hashtable, keybuf, valbuf); /*G*/ break; 
      case 3: set(hashtable, keybuf, valbuf); delete(hashtable, keybuf); /*SD*/ break; 
      case 6: set(hashtable, keybuf, valbuf); get(hashtable, keybuf, valbuf); /*SG*/ break; 
      case 5: get(hashtable, keybuf, valbuf); delete(hashtable, keybuf); /*GD*/ break; 
      case 7: set(hashtable, keybuf, valbuf); get(hashtable, keybuf, valbuf); delete(hashtable, keybuf); /*SGD*/ break; 
      default: fprintf(stdout,"Unknown command.\n")/*Fehlermeldung*/; break; 
     } 
     buffer[0] = buffer[0]|0b00001000; 
     send(new, buffer, sizeof(buffer), 0); 
     for(line = 0; line < numbytes; ++line){ 
      printf("Sending Byte#%d = ",line); 
      for(bitcounter = 0; bitcounter < 8; bitcounter++){ 
       printf("%d ", (buffer[line] >> bitcounter)&1); 
+1

Вы забыли сказать нам, какая линия ошибка компилятора или предупреждение, что происходит на. –

+0

Не связано с проблемой вообще (так как мне нужно будет увидеть полный, компилируемый исходный код, чтобы найти точную проблему), но: вы обычно хотите сохранить исходный хэш с каждым элементом данных по двум причинам: 1) вы можете сравнить полные хэши, прежде чем сравнивать ключевые строки; 2) вы можете выращивать стол без пересчета всех хэшей. (Конечно, вы все еще используете 'hash% tablesize', чтобы узнать слот в хэш-таблице.) –

+0

@JohnZwinck см. Это ...' (строка 53) -> unsigned long hval = hash (key); ' –

ответ

0

Я вижу несколько гольцов буферов в вашем коде, вы пытаетесь использовать их в качестве ключей? Например, вы можете инициализировать их следующим образом:

char s[INET6_ADDRSTRLEN] = ""; 

Этот код имитирует точно такое же поведение:

#include <stdio.h> 

unsigned int hash(char *str) { 
    unsigned int hash = 5381; 
    int c; 

    while ((c = *str++)) 
    hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ 

    return hash % 128; 
} 

int main(int argc, char *argv[]) { 
    char initialized[20] = "hello"; 
    printf("hash(initialized) = %u\n", hash(initialized)); 

    char not_initialized[20]; 
    printf("hash(not_initialized) = %u\n", hash(not_initialized)); 
    return 0; 
}