c - 我的 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<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;
}
请注意void add (char[])
,为什么没有输出[4] The -> App
?即使我改成DF *temp=df[idx];
它DF *temp=df[idx]->next;
也没有什么区别。但是如果我把它的功能改成这个,
void add (char str[])
{
int idx=hash (str);
if (df[idx])
{
DF *temp=df[idx];
while (temp->next) temp=temp->next;
temp->next=ND (str);
}
else df[idx]=ND (str);
}
它打印出来[4] The -> App
。那么,这两种算法有什么区别呢?
解决方案
第一种方式:
temp=ND (str);
只需分配一个局部变量,因此它对函数外部没有影响,因为您有内存泄漏(但未修改列表,未添加元素)
但第二种方式:
temp->next=ND (str);
修改链表
要工作,您可以修改第一种方法:
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:
strcpy (node->str, str); node->D=1;
很危险,因为str可能太长而无法保存node->str
,您可以使用strncpy
当要保存的字符串很小时,您会失去记忆。
不使用数组作为字段str而是使用 achar*
并复制字符串(strdup
例如)怎么样?
在哈希中你遍历字符串两次,你不需要计算strlen并且可以使用
for (int x=0; str[x] != 0; x++) sum+=str[x];
推荐阅读
- javascript - 获取和验证复选框和单选按钮的值
- scala - Scala:不可参数化提取器的解决方法
- javascript - Mongoose:按嵌套字段排序
- firebase - 在 Firebase Cloud Functions 中加密数据
- jenkins - 如何将用户输入的密码与凭据密码进行比较
- python-2.7 - Tensorflow Python:前馈网络在大小上失败?
- c# - WPF 错误中的 System.Drawing.Bitmap
- r - 整洁的评估范围是否有限制?
- python-3.x - 程序不会写入指定的文本文件
- list - 递归检查列表中的所有元素是否是Prolog中的某个值