实现哈希表

时间:2017-11-26 00:35:02

标签: c segmentation-fault hashtable

执行关系数据结构项目,我将事物组织到哈希表中。到目前为止,我已经制作了一个插入和查找方法,并且没有错误。当我尝试运行代码时,我得到了这个:

"插入CSG游戏" "分段错误11"

我认为我没有正确地对某些内容进行操作,但我无法弄清楚它是什么,并且考虑到它正在说"插入CSG操作"我不认为我的createHashTable函数存在问题。继承我的代码

头文件:CSG.h

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

typedef struct CSG{
    char* Course;
    char* StudentId;
    char* Grade;
    struct CSG *next;

}CSG;

typedef struct CSGHASH{

    int size;
    CSG** table;

}CSGHASH;

CSGHASH* createHashTable(int size);

int hash(int CN);

CSG* makeCSG(char* Course, char* StudentId, char* Grade);

void printCSG(CSG guy);

//void printCSGLIST(CSGLIST guy);

int toInt(char* x);

CSG* lookup(CSGHASH *hashtable, char* course, char* StudentId, char* grade);

int insert(CSG* newGuy, CSGHASH* hashtable);

CSG.c

CSGHASH* createHashTable(int size){

    CSGHASH* hashtable = NULL;

    if(size<1)
        return NULL; // table cant be less than length of 1

    if((hashtable = malloc(sizeof(CSGHASH*)))== NULL)
        return NULL;

    if((hashtable->table = malloc(sizeof(CSG*) * size)) == NULL)
        return NULL;

    for(int i = 0; i<size; i++){

        hashtable->table[i] = malloc(sizeof(CSG));
        hashtable->table[i] = NULL;
        //hashtable->table[i]->next = NULL;
    }

    hashtable->size = size;

    return hashtable;
}

int hash(int CN){

    return CN%6;
}

CSG* makeCSG(char* Course, char* StudentId, char* Grade){

    //struct CSG tempCSG = malloc(sizeof(CSG));
    CSG* tempCSG = malloc(sizeof(CSG*));
    strcpy(tempCSG->Course, Course);
    strcpy(tempCSG->StudentId, StudentId);
    strcpy(tempCSG->Grade, Grade);
    return tempCSG;
}

void printCSG(CSG guy){

    printf("course: %s\n", guy.Course);
    printf("StudentId: %s\n", guy.StudentId);
    printf("Grade: %s\n", guy.Grade);
}

// void printCSGLIST(CSGLIST guy){


// }

int toInt(char* x){

    int count = 0;
    for(int i = 0; i< strlen(x); i++)
        count += (int) i;
    return count;
}


CSG* lookup(CSGHASH *hashtable, char* course, char* StudentId, char* grade){

    CSG* list;
    unsigned int hashNum = hash(toInt(course));

    for(list = hashtable->table[hashNum]; list!= NULL; list = list->next){

        if(strcmp(StudentId, list->StudentId) == 0){

            printf("Course: %s\n", list->Course);
            printf("Student ID: %s\n", list->StudentId);
            printf("Grade: %s\n", list->Grade);
            return list;
        }
    }
    printf("doesn't exist\n");
    return NULL;
}

int insert(CSG* newGuy, CSGHASH* hashtable){

    CSG* list;
    CSG* currList;
    unsigned int hashNum = hash(toInt(newGuy->Course));

    list = malloc(sizeof(CSG));

    currList = lookup(hashtable, newGuy-> Course, newGuy-> StudentId, newGuy-> Grade);

    if(currList != NULL){

        printf("already exists\n");
        return 2;
    }

    list->Grade = strdup(newGuy->Grade);
    list->StudentId = strdup(newGuy->StudentId);
    list->Course = strdup(newGuy->Course);
    list->next = hashtable->table[hashNum];
    hashtable->table[hashNum] = list;

    printf("CSG inserted\n");
    return 0;
}

主档

/*
main4.c
*/

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

int main(int argc, char *argv[]){

CSGHASH *testHash = createHashTable(47);


printf("inserting CSG tuples \n");

CSG* tuple1 = makeCSG("CSC101", "12345", "A+");
CSG* tuple2 = makeCSG("CSC101", "67890", "B");
CSG* tuple3 = makeCSG("EE200", "67890", "B+");
CSG* tuple4 = makeCSG("EE200", "45213", "D");
CSG* tuple5 = makeCSG("CSC173", "98765", "C");
CSG* tuple6 = makeCSG("MTH142", "47474", "A");

insert(tuple1, testHash);
lookup(testHash, "CSC101", "12345", "*");

//printCSGLIST(lookup(tester, "CSC101", "12345", "*"));
}

如果有人能弄清楚我做错了什么,我真的很感激(抱歉,我知道要追查的内容很多)。

更新

经过一些调试后,问题就出现在makeCSG函数中。希望能让它更容易追踪

3 个答案:

答案 0 :(得分:0)

快速通过了:

  if((hashtable = malloc(sizeof(CSGHASH*)))== NULL)

错误,这将为指向CSGHASH的指针分配足够的存储空间,而不是CSGHASH本身。认为你想摆脱星号。以下malloc()也会遭遇同样的命运。

答案 1 :(得分:0)

来自CSG.h:

typedef struct CSG{
    char* Course;
    char* StudentId;
    char* Grade;
    struct CSG *next;

}CSG;

并在makeCSG()你正在做的事情:

CSG* makeCSG(char* Course, char* StudentId, char* Grade){

    //struct CSG tempCSG = malloc(sizeof(CSG));
    CSG* tempCSG = malloc(sizeof(CSG*));
    strcpy(tempCSG->Course, Course);
    strcpy(tempCSG->StudentId, StudentId);
    strcpy(tempCSG->Grade, Grade);
    return tempCSG;
}

makeCSG()中有几个问题:

第一个问题:

CSG* tempCSG = malloc(sizeof(CSG*));

此处,tempCSG是指向CSG的指针。所以你应该:

CSG* tempCSG = malloc(sizeof(CSG));

createHashTable()中的类似问题:

if((hashtable = malloc(sizeof(CSGHASH*)))== NULL)

这应该是:

if((hashtable = malloc(sizeof(CSGHASH)))== NULL)

第二个问题:

strcpy(tempCSG->Course, Course);
strcpy(tempCSG->StudentId, StudentId);
strcpy(tempCSG->Grade, Grade);

此处,CourseStudentIdGrade属于char *类型,并且您正在尝试将某些值复制到您未分配内存<的指针/ strong>即可。在使用之前分配内存。

首先你应该做这样的事情:

CSG* tempCSG = malloc(sizeof(CSG));
tempCSG->Course = malloc(100);
tempCSG->StudentId = malloc(20);
tempCSG->Grade = malloc(10);

然后

strcpy(tempCSG->Course, Course);
strcpy(tempCSG->StudentId, StudentId);
strcpy(tempCSG->Grade, Grade);
tempCSG->next = NULL;

另外,请务必在每次malloc来电后查看malloc返回。

答案 2 :(得分:0)

基本上所有包含char*的内容都是错误的。您没有分配将数据复制到这些缓冲区所需的内存,实际上您根本没有初始化它们。

您的代码错误的简化版本:

char* Course;
strcpy(Course, "CSC101");

这是因为我们从未分配Course而导致致命错误。

对于结构中的malloc()中的每一个,您必须char*足够的空间来容纳数据,或者将它们声明为数组,因此它们已经在为您保留内存时分配它们所处的结构,但在编译时确定了固定的大小。

示例:

typedef struct CSG
{
    char Course[16];
    char StudentId[16];
    char Grade[16];
    struct CSG *next;
} CSG;

这确实是解决问题的最简单方法,如果您希望创建某种基本数据库,可以在文件上轻松存储和恢复此结构,并保持代码更清晰,避免过多的内存管理到处都是malloc()free()