当通过void指针值改变并获得分段错误?

时间:2018-01-15 00:09:57

标签: c segmentation-fault hashtable void-pointers

背景:创建一个哈希表库,允许3个不同的实现2解决与开放寻址的冲突(一个是固定大小而另一个是动态的)和第三个使用链接列表单独链接

问题背景:通过创建固定大小的开放式寻址开始。起初,这种方法非常完美,但必须进行一些更改以适应库以满足其他两个实现。为此,我需要记录列表的大小(使用的结构)和void指针作为开放寻址的结构,并且单独的链接是不同的。

实际问题:由于某些原因,我的保存功能在调试时不再有效我发现有两个问题我无法辨别原因:

  1. 将一个结构通过一个void指针传递给这个函数 值变化(请注意,这只发生在这个函数中 虽然我在其余的功能中使用相同的方法 没有得到同样的问题)
  2. 我在fprintf语句中遇到了分段错误(在上述修订之前已经有效了。
  3. 保存问题中的功能

        void hashtbl_savetofile(void* hashtbl, const char *path){
            Hashtbl *temp;
            temp = hashtbl;
            int i;
    
            FILE *f = fopen(path, "w");
    
            if (f == NULL){
                printf("FILE NOT FOUND!");
            }else {
                for(i = 0; i<SIZE; i++) {
                    fprintf(f, "%s", temp->data[i].subscript); // segmentation fault occurs
                    fprintf(f, "%s", temp->data[i].value);
                }
                fclose(f);
                free(temp);
            }
        }
    

    标题文件

        #ifndef TASK2_HASHTABLE_H
        #define TASK2_HASHTABLE_H
    
        #define SIZE 20
        #define MAX_LENGTH 100
        #define INIT_SIZE 64000
    
        typedef struct Data_struct{
            char *subscript;
            char *value;
        } Data;
    
        typedef struct Hashtbls{
            int numberOfEntries;
            int allocatedEntries;
            Data *data;
        }Hashtbl;
    
        int hashtbl_hashKey(void* hashtbl, const char *subscript ); // generates hash key for hash table
        Data hashtbl_lookup(void* hashtbl, const char *subscript); //looks up and retrieves a given subscript and its value hash table
        void* hashtbl_insert(void* hashtbl, const char *subscript, const char *value); //adds a given subscript and its value to hash table
        void* hashtbl_delete(void* hashtbl, const char *subscript); //deletes a given subscript and its value from hash table
        void hashtbl_savetofile(void* hashtbl, const char *path); //saves hash table to file
        void* hashtbl_loadfromfile(void* hashtbl, const char *path); //loads hash table from file
        void* hashtbl_init();
    
        #endif //TASK2_HASHTABLE_H
    

    测试驱动程序

        #include <stdio.h>
        #include "hashtable.h"
    
        int main() {
            Hashtbl *nums;
            Data d;
            nums = hashtbl_init();
            hashtbl_insert(nums, "tea", "40c");
            hashtbl_insert(nums, "coffee", "50c");
            hashtbl_insert(nums, "biscuit", "4c");
            hashtbl_insert(nums, "tart", "30c");
            d = hashtbl_lookup(nums, "tart");
            printf("%s", d.subscript);
            printf("%s", d.value);
            hashtbl_savetofile(nums, "test.txt");
        }
    

    实施(供参考):

        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include "hashtable.h"
    
        void* hashtbl_init(){ //initiates static 2D hash table when called
            Hashtbl* hashtbl;
            hashtbl = malloc(INIT_SIZE);
            hashtbl->numberOfEntries = SIZE;
            hashtbl->allocatedEntries = 0;
            hashtbl->data = calloc(SIZE, sizeof(Data));
            for(int i = 0; i<SIZE; i++){
                hashtbl->data[i].subscript = malloc(MAX_LENGTH + 1);
                strcpy(hashtbl->data[i].subscript, "ZERO\n");
    
                hashtbl->data[i].value = malloc(MAX_LENGTH + 1);
                strcpy(hashtbl->data[i].value, "ZERO\n");
            }
            return hashtbl;
        }
    
        Data hashtbl_lookup(void* hashtbl, const char *subscript){
            Data item;
            Hashtbl *temp;
            temp = hashtbl;
            int i = 0;
            char *c;
            c = malloc(MAX_LENGTH);
            strcpy(c, subscript);
            strct(c, "\n");
    
            while (strcmp(temp->data[(hashtbl_hashKey(hashtbl, subscript)+i)].subscript, c) != 0){
                i++;
                if(hashtbl_hashKey(hashtbl, subscript)+i == temp->numberOfEntries){
                    break;
                }
            }
            if(hashtbl_hashKey(hashtbl, subscript)+i != temp->numberOfEntries) {
                if(strcmp(temp->data[(hashtbl_hashKey(hashtbl, subscript)+i)].subscript, c) == 0) {
                    item.subscript = temp->data[(hashtbl_hashKey(hashtbl, subscript) + i)].subscript;
                    item.value = temp->data[(hashtbl_hashKey(hashtbl, subscript) + i)].value;
                }
            }else{
                for(i = 0; i<hashtbl_hashKey(hashtbl, subscript); i++){
                    if(strcmp(temp->data[i].subscript, c) == 0){
                        item.subscript = temp->data[i].subscript;
                        item.value = temp->data[i].value;
                    }
                }
            }
            free(hashtbl);
            free(c);
            free(temp);
    
           return item;//what if not found
        }
    
        void* hashtbl_insert(void* hashtbl, const char *subscript, const char *value){
            Hashtbl *temp;
            temp = hashtbl;
            int i = 0;
            char *c1;
            c1 = malloc(MAX_LENGTH);
            strcpy(c1, subscript);
            strcat(c1, "\n");
            char *c2;
            c2 = malloc(MAX_LENGTH);
            strcpy(c2, value);
            strcat(c2, "\n");
    
            if(temp->allocatedEntries == temp->numberOfEntries){
                free(c1);
                free(c2);
                free(temp);
                return hashtbl;
            }else {
                if (strcmp(temp->data[hashtbl_hashKey(hashtbl, subscript) + i].subscript, "ZERO\n") == 0) {
                    temp->data[hashtbl_hashKey(hashtbl, subscript)].subscript = c1;
                    temp->data[hashtbl_hashKey(hashtbl, subscript)].value = c2;
                    temp->allocatedEntries++;
                } else {
                    while ((strcmp(temp->data[hashtbl_hashKey(hashtbl, subscript) + i].subscript, "ZERO\n") != 0)) {
                        i++;
                        if (hashtbl_hashKey(hashtbl, subscript) + i == temp->numberOfEntries) {
                            break;
                        }
                    }
                    if (hashtbl_hashKey(hashtbl, subscript) + i != temp->numberOfEntries) {
                        if ((strcmp(temp->data[hashtbl_hashKey(hashtbl, subscript) + i].subscript, "ZERO\n") == 0)) {
                            temp->data[(hashtbl_hashKey(hashtbl, subscript) + i)].subscript = c1;
                            temp->data[(hashtbl_hashKey(hashtbl, subscript) + i)].value = c2;
                            temp->allocatedEntries++;
                        }
                    } else {
                        for (i = 0; i < hashtbl_hashKey(hashtbl, subscript); i++) {
                            if (strcmp(temp->data[i].subscript, "ZERO\n") == 0) {
                                temp->data[i].subscript = c1;
                                temp->data[i].value = c2;
                                temp->allocatedEntries++;
                            }
                        }
                    }
                }
                free(c1);
                free(c2);
    
                return temp;
            }
        }
    
        void* hashtbl_delete(void* hashtbl, const char *subscript){
            Hashtbl *temp;
            temp = hashtbl;
            int i = 0;
            int j = 0;
            char *c;
            c = malloc(MAX_LENGTH);
            strcpy(c, subscript);
            strcat(c, "\n");
    
            while ((strcmp(temp->data[(hashtbl_hashKey(hashtbl, subscript)+i)].subscript, c) != 0)){
                i++;
                if((hashtbl_hashKey(hashtbl, subscript)+i) == temp->numberOfEntries) {
                    break;
                }
            }
            if(hashtbl_hashKey(hashtbl, subscript)+i != temp->numberOfEntries) {
                if(strcmp(temp->data[(hashtbl_hashKey(hashtbl, subscript)+i)].subscript, c) == 0) {
                    temp->data[(hashtbl_hashKey(hashtbl, subscript) + i)].subscript = "ZERO\n";
                    temp->data[(hashtbl_hashKey(hashtbl, subscript) + i)].value = "ZERO\n";
                    temp->allocatedEntries--;
                }
            }else{
                for(j = 0; j<hashtbl_hashKey(hashtbl, subscript); j++){
                    if(strcmp(temp->data[j].subscript, c) == 0){
                        temp->data[j].subscript = "ZERO\n";
                        temp->data[j].value = "ZERO\n";
                        temp->allocatedEntries--;
                    }
                }
            }
            hashtbl=temp;
            free(c);
            free(temp);
            return hashtbl;
        }
    
        void hashtbl_savetofile(void* hashtbl, const char *path){
            //provided above
        }
    
        void* hashtbl_loadfromfile(void* hashtbl, const char *path){
            Hashtbl *temp;
            temp = hashtbl;
            temp->allocatedEntries=0;
            int i = 0;
            int j =0;
            int c = 0;
            char line[100];
            char* string[temp->numberOfEntries];
    
            FILE *f = fopen(path, "r");
    
            if(f == NULL){
                free(temp);
                return NULL;
            }else {
                while(fgets(line, sizeof line, f)){
                    j++;
                }
                if((j/2)>temp->numberOfEntries){
                    free(temp);
                    return NULL;
                }else {
                    while (fgets(line, sizeof line, f)) {
                        string[i] = malloc(strlen(line) + 1);
                        if (string[i] == NULL) {
                            break;
                            return NULL;
                        } else {
                            strcpy(string[i], line);
                            i++;
                            if (i == sizeof string / sizeof *string) {
                                break;
                            }
                        }
                    }
                    fclose(f);
    
                    for (i = 0; i < (SIZE * 2); i++) {
                        if (strlen(string[i]) >= MAX_LENGTH) {
                            char *k = realloc(temp->data[c].subscript, strlen(string[i]));
                            if (k == NULL) {
                                break;
                                return NULL;
                            } else {
                                temp->data[c].subscript = k;
                                strcpy(temp->data[c].subscript, string[i]);
                                if(temp->data[c].subscript != "ZERO\n"){
                                    temp->allocatedEntries++;
                                }
                                i++;
                                c++;
                            }
                        } else {
                            temp->data[c].subscript = malloc(strlen(string[i]) + 1);
                            strcpy(temp->data[c].subscript, string[i]);
                            if(temp->data[c].subscript != "ZERO\n"){
                                temp->allocatedEntries++;
                            }
                            i++;
                            c++;
                        }
                    }
                    c = 0;
                    for (i = 1; i < (SIZE * 2); i++) {
                        if (strlen(string[i]) >= MAX_LENGTH) {
                            char *k = realloc(temp->data[c].value, strlen(string[i]));
                            if (k == NULL) {
                                break;
                                return NULL;
                            } else {
                                temp->data[c].value = k;
                                strcpy(temp->data[c].value, string[i]);
                                i++;
                                c++;
                            }
                        } else {
                            temp->data[c].value = malloc(strlen(string[i]) + 1);
                            strcpy(temp->data[c].value, string[i]);
                            i++;
                            c++;
                        }
                    }
                    hashtbl=temp;
                    free(temp);
                    free(string);
                    return hashtbl;
                }
            }
        }
    
        int hashtbl_hashKey(void* hashtbl, const char *subscript){
            int i;
            int h = 0;
    
            for(i = 0; subscript[i]; i++){
                h += subscript[i];
            }
            h = h%SIZE;
            return h;
        }
    

0 个答案:

没有答案