C “哈希表”;未初始化的值是由堆栈分配创建的;

C “哈希表”;未初始化的值是由堆栈分配创建的;,c,hashtable,C,Hashtable,我们正在尝试设置一个哈希表和一些过程,这些过程将设置、获取和删除表中的值。我们在第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== U

我们正在尝试设置一个哈希表和一些过程,这些过程将设置、获取和删除表中的值。我们在第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];
}
typedef结构KeyVal{
无符号字符*值;
无符号字符*键;
结构KeyVal*next;
}基瓦尔;
无符号长哈希(无符号字符*str)
{
无符号长散列=5381;
INTC;
(第35行)->while(c=*str++)
hash=((hash unsigned long hval=hash(key);
if(哈希表[hval]==NULL){
KeyVal*runvar=calloc(1,sizeof(KeyVal));
runvar->key=key;
runvar->value=value;
runvar->next=NULL;
hashtable[hval]=runvar;
fprintf(stdout,“成功设置1\n”);
返回1;
}否则{
KeyVal*计数器=哈希表[hval];
KeyVal*prev=计数器;
while(计数器!=NULL){
prev=计数器;
计数器=计数器->下一步;
}
KeyVal*runvar=calloc(1,sizeof(KeyVal));
runvar->key=key;
runvar->value=value;
runvar->next=NULL;
prev->next=runvar;
fprintf(stdout,“成功设置2\n”);
返回2;
}
返回-1;
}
(第133行)->int main(int argc,char*argv[]){
int sock,新建,状态,命令;
结构addrinfo提示,*serverinfo,*p;
结构sockaddr\u存储它们的地址;
袜子的大小;
int yes=1;
字符s[INET6_ADDRSTRLEN];
无符号整数字节=0;
字符缓冲区[128];
int行,transid,位计数器=0;
无符号短keylenmb,keylenLSB,keylen,vallenMSB,vallenLSB,vallen=0;
KeyVal*哈希表[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);
unsigned char keybuf[MAXBUFFERLEN],valbuf[MAXBUFFERLEN]={0};
而第(1)款{
sin_size=(socklen_t)sizeof(他们的地址);
新=接受(sock,(struct sockaddr*)及其地址和大小);
如果(新==-1){
佩罗(“接受”);
继续;
}
inet_ntop(他们的_addr.ss_系列,get_in_addr((struct sockaddr*)和他们的_addr),s,sizeof s);
printf(“服务器:已从%s获得连接\n”,s);
如果((numbytes=recv(new,buffer,sizeof(buffer),0))<0){
perror(“recv”);
出口(1);
}
printf(“%d\n”,numbytes);
用于(行=0;行<字节数;++行){
printf(“字节#%d=,行);
用于(位计数器=0;位计数器<8;位计数器++){
printf(“%d”,(缓冲区[行]>>位计数器)&1);
}
printf(“\n”);
道岔(线路){
案例0:开关(缓冲器[线路]){
案例1:command=(buffer[line]);fprintf(stdout,“line=%d,command=%d\n”,line,command);/*d*/break;
案例2:command=(buffer[line]);fprintf(stdout,“line=%d,command=%d\n”,line,command);/*S*/break;
案例3:command=(buffer[line]);fprintf(stdout,“line=%d,command=%d\n”,line,command);/*SD*/break;
案例4:command=(buffer[line]);fprintf(stdout,“line=%d,command=%d\n”,line,command);/*G*/break;
案例5:command=(buffer[line]);fprintf(stdout,“line=%d,command=%d\n”,line,command);/*GD*/break;
案例6:command=(buffer[line]);fprintf(stdout,“line=%d,command=%d\n”,line,command);/*SG*/break;
案例7:command=(buffer[line]);fprintf(stdout,“line=%d,command=%d\n”,line,command);/*SGD*/break;
默认值:fprintf(stdout,“不是有效命令”;/*Fehlermeldung*/break;
}
情况1:transid=缓冲区[行];中断;
情况2:keylenMSB=buffer[line];keylenMSB=keylenMSB>bitcounter)&1);

我在您的代码中看到了两个字符缓冲区,您是否试图将它们用作键?例如,您可以这样初始化它们:

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;
}
#包括
无符号整数散列(char*str){
无符号整数散列=5381;
INTC;
而((c=*str++)

hash=((hash您忘记告诉我们编译器错误或警告发生在哪一行。与当前的问题毫无关系(因为我需要查看完整的可编译源代码才能找到确切的问题),但是:您通常希望将原始hash与每个数据元素一起存储,原因有二:1)然后,您可以在比较键字符串之前比较完整的散列;2)您可以在不重新计算所有散列的情况下增长表。(当然,您仍然使用
hash%tablesize
来查找散列表中的插槽。)您介意创建一个吗?可能是
main()中出错了
未初始化的值是由0x40112A:main(hashserver.c:133)上的堆栈分配创建的。
,您是否也可以显示该行?我猜OP在第一次调用
set()之前忘记将
哈希表[]
指针清除为NULL
。不,等等;我想这会影响下一行。因此,也许OP调用
set()
,使用
指向
缓冲区[]
,而没有初始化
缓冲区[]
?(迈克尔·沃尔兹在下面首先指出了这一点,他这么做的时候我还在编辑这条评论。)