龟儿子苓膏 2022-05-18 14:35 采纳率: 81.3%
浏览 74
已结题

求读取无效数据和读取发生冲突的解决方法

问题遇到的现象和发生背景
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
//为保证平均查找长度不超过2,哈希表的长度为45
#define NULL 0
typedef int KeyType;//起别名,方便辨别
typedef struct {
    KeyType key;//人名对应的编号
    char* name;//人名
}Table;

int Haxi(KeyType key)//利用除留余数法构造哈希函数
{
    int i, p, flag;
    int length = 45;
    for (p = length; p >= 2; p--)//不超过表长的最大素数
    {
        for (i = 2, flag = 1; i <= p / 2 && flag; i++)//通过不断的除来判断
        {
            if (p % i == 0)
                flag = 0;//不是则终止此循环
        }
        if (flag == 1)
            break;//是的话终止循环
    }
    return key % p;//哈希地址
}

void Datatable(Table** ST, int n, int length)//储存已知的30个人名,按照输入的顺序给每个人名编号
{
    int i;
    (*ST) = (Table*)malloc(length * sizeof(Table));//动态分配内存的起始地址,和表长大小一样
    if (*ST) {
        printf("\n 请输入30个人名(编号随机): ");
        for (i = 0; i < n; i++)
        {
            printf("\n第%d个:  (编号 空格 人名)", i + 1);
            fflush(stdin);/*清除输入缓冲区*/
            scanf_s("%d %s", &((*ST)[i].key), (*ST)[i].name, 20);
        }
    }
}

void Haxitable(Table** HAXI, Table* ST, int n)//建立哈希表
{
    int length = 45;
    int i, j;
    (*HAXI) = (Table*)malloc(length * sizeof(Table));//分配地址
    if (*HAXI) {
        for (i = 0; i < length; i++)
        {
            (*HAXI)[i].key = NULL;//初始化
            (*HAXI)[i].name = 0;
        }
        for (i = 0; i < n; i++)
        {
            j = Haxi(ST[i].key);//获得哈希地址
            while ((*HAXI)[j].key != NULL)//利用线性探测再散列解决冲突
                j = (j + 1) % length;
            (*HAXI)[j].key = ST[i].key;//将数据放入哈希表
            (*HAXI)[j].name = ST[i].name;
        }
        //    for(i=0;i<n;i++)
        //        printf("数据库第%d个是%d\n",i,ST[i].key);//验证思路
        printf("\n哈希表制作完成\n");
    }
}
void Show(Table* HAXI, int length)
{
    int i;
    printf("\n          ****************哈希表**************\n");
    printf("键:       *****");
    for (i = 0; i < length; i++)
        printf("%6d", HAXI[i].key);
    printf("\n");
    printf("值:       *****");
    
    for (i = 0; i < length; i++) {
        if(HAXI[i].name!=NULL)
            printf("%s", HAXI[i].name);
    }
        printf("\n");
    printf("地址:     *****");
    for (i = 0; i < length; i++)
        printf("%6d", i);
    printf("\n");
}
int Search(Table* HAXI, KeyType key, int length)//查找方法
{
    int i;
    i = Haxi(key);//哈希函数获得位置
    while (HAXI[i].key != 0 && HAXI[i].key != key)
    {
        i = (i + 1) % length;//利用构造时解决冲突的方法解决冲突
    }
    if (HAXI[i].key == 0)
        return -1;
    else
        return i;
}
int main() {
    Table* ST, * HAXI;
    KeyType key;
    int n=3, length=4;

        printf("建立哈希表:\n");    
            Datatable(&ST, n, length);
            Haxitable(&HAXI, ST, n);
            printf("显示哈希表\n");
            Show(HAXI, length);
            printf("请输入想要查找的编号:");
            scanf_s("%d", &key);
            if (Search(HAXI, key, length) == -1)
                printf("未查询到");
            else
                printf("查找成功!位置是%d值为%s", Search(HAXI, key, length), HAXI[Search(HAXI, key, length)].name);
            free(ST);
    }

输入如图内容之后出现两个问题

img


一个是读取无效

img


一个是0x00007FFCE75A6191 (ucrtbased.dll)处(位于 haxibiao.exe 中)引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。

img

想要输入几个编号和对应的名字,利用线性探测再散列放入哈希表中,然后再输出存好之后的表的内容

展开全部

  • 写回答

1条回答 默认 最新

  • SmallAntJ 2022-05-18 19:21
    关注

    因为定义Table结构体的时候,name只是char指针而没有分配空间,所以在Datatable()中输入数据的时候写入了未申请的内存空间。创建ST的时候需要为name分配内存空间。

    一共修改了3处:
    1、第34行

    (*ST) = (Table*)malloc(length * sizeof(Table));//动态分配内存的起始地址,和表长大小一样
    for (i = 0; i < n; i++) { (*ST)[i].name = (char*)malloc(n * sizeof(20)); } //为每一个元素的name字段动态分配内存
    

    2、第72行

    int i;
    length = 45;//哈希表长度为45
    

    3、第119行

    //先释放HAXI,再释放name,最后释放ST
    free(HAXI);//释放HAXI
    int i;
    for (i = 0; i < n; i++) free(ST[i].name);//释放name
    free(ST);//释放ST
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

问题事件

  • 系统已结题 5月26日
  • 已采纳回答 5月19日
  • 创建了问题 5月18日

悬赏问题

  • ¥15 已知手指抓握过程中掌指关节、手指各关节和指尖每一帧的坐标,用贝塞尔曲线可以拟合手指抓握的运动轨迹吗?
  • ¥50 libwebsockets 如何添加其他socket事件回调
  • ¥50 实现画布拖拽算子排布,通过flink实现算子编排计算,请提供思路
  • ¥15 esium自定义材质拉伸问题
  • ¥15 cmake+mingw使用<mysqlx/xdevapi.h>报错
  • ¥15 eNSP中防火墙的使用
  • ¥15 不能对数据库增删改但是可以查询
  • ¥15 关于#mlnet#的问题:mlnet相关请求(语言-c#)
  • ¥15 lvgl7.11怎么做出文字被选中的效果
  • ¥50 如何快速查看手机目标app的主要服务器ip
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部