C 哈希表或I'中的指针损坏;我错过了什么?

C 哈希表或I'中的指针损坏;我错过了什么?,c,pointers,hashtable,C,Pointers,Hashtable,这是我的密码 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct DF { char str[101]; int D; struct DF *next; } DF; DF *df[5]; int hash (char str[]) { int sum=0, len=strlen (str); for (int x=0; x

这是我的密码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct DF
{
    char str[101];
    int D;
    struct DF *next;
} DF;
DF *df[5];

int hash (char str[])
{
    int sum=0, len=strlen (str);
    for (int x=0; x<len; x++) sum+=str[x];
    
    return sum%5;
}

DF* ND (char str[])
{
    DF *node=(DF*) malloc (sizeof (DF));
    strcpy (node->str, str); node->D=1;
    node->next=NULL;
    
    return node;
}

void add (char str[])
{
    int idx=hash (str);
    if (df[idx])
    {
        DF *temp=df[idx];
        while (temp) temp=temp->next;
        temp=ND (str);
    }
    else df[idx]=ND (str);
}

int main (void)
{
    char str1[]="The"; add (str1);
    char str2[]="App"; add (str2);
    
    if (df[4])
    {
        printf ("[4] %s", df[4]->str);
        DF *temp=df[4]->next;
        while (temp)
        {
            printf (" -> %s", temp->str);
            temp=temp->next;
        }
        puts ("");
    }
    
    return 0;
}
它打印出->应用程序的
[4]。那么,这两种算法之间有什么区别呢?

第一种方法是:

只需指定一个局部变量,这样它就不会对函数外部产生影响,因为您存在内存泄漏(但列表未修改,元素未添加)

但在第二方面:

修改链接列表

要工作,您可以修改第一种方法:

void add (char str[])
{
    int idx=hash (str);
    if (df[idx])
    {
        DF **temp=&df[idx];
        while (*temp) temp=&(*temp)->next;
        *temp=ND (str);
    }
    else df[idx]=ND (str);
}
但这并不复杂,除非您想删除
if

void add (char str[])
{
    DF ** temp=&df[hash(str)];
    
    while (*temp)
      temp=&(*temp)->next;
    *temp=ND (str);
}
注意:在同义词列表的末尾添加一个新单元格是没有用的,您没有全局顺序,您可以直接做:

void add (char str[])
{
    DF * temp=ND (str);
    int idx=hash (str);

    temp->next = df[idx];
    df[idx] = temp;
}
在ND中:

是危险的,因为str太长,无法保存在
节点->str
中,您可以使用strncpy

当要保存的字符串很小时,你就会失去记忆

对于字段str不使用数组,而是使用
char*
并复制字符串(例如
strdup
)怎么样

在哈希中,您将字符串遍历两次,不需要计算strlen,可以使用

for (int x=0; str[x] != 0; x++) sum+=str[x];

我个人觉得很难理解/阅读你的代码。你可以添加一些注释行,让其他人知道程序应该做什么吗?@BlayerBond不需要它,只要阅读代码就可以看到problem@bruno,为了确保我解决了正确的问题,最好知道什么是
DF
(数据帧?)、
D
(数据?)和
ND
(新数据?),不必通读整个代码,但可能这只是因为我自己没有用C制作哈希表:/@BlayerBond我同意字段D是模糊的/没有用的,因为它只设置为1。对于其他人来说,实现哈希表是一个很好的练习,当我们执行
inti=4时,有很多方法可以做(例如,当元素太多时,同义词列表的数组可能会增长,从而产生一个重哈希);int j=i;j=j+1
i
4还是5?你能解释一下你所说的内存泄漏吗?所以
temp->next=ND(str)
修改链接列表,因为它指向
next
,对吗?因为它与前一个add相同(*temp).next=ND(str)
right?@LastSecond959 temp如果不为NULL赋值则来自前一个add,因此
temp->next=ND(str)
修改旧单元格下一个字段。是
temp->
(*temp)。
是相同的,第一个是第二个的快捷方式
void add (char str[])
{
    DF ** temp=&df[hash(str)];
    
    while (*temp)
      temp=&(*temp)->next;
    *temp=ND (str);
}
void add (char str[])
{
    DF * temp=ND (str);
    int idx=hash (str);

    temp->next = df[idx];
    df[idx] = temp;
}
strcpy (node->str, str); node->D=1;
for (int x=0; str[x] != 0; x++) sum+=str[x];