2016-11-21 41 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的练习,我们以这种方式从客户端接收命令。在最后,我们调用set()函数:

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看到这个......'(line 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; 
}