【问题标题】:Getting a segmentation fault error on an Open Addressing Hash Map?在开放寻址哈希映射上出现分段错误错误?
【发布时间】:2020-05-15 14:41:14
【问题描述】:

我在插入函数的某处遇到分段错误错误。它说这是由于“strcmp”比较之一,但在查看所有这些比较后我找不到问题。

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

#define INITIAL_CAPACITY 8

typedef struct node
{
    unsigned int val;
    char *key;
    bool del;
} Node;

typedef Node * NodePtr;

typedef struct hashMap
{
    NodePtr array;
    size_t capacity;
    size_t size;
} HashMap;

typedef HashMap * HMPtr;

//|-------------------------

HMPtr create();
void insert(HMPtr map, char *str);
//y
void resize_insert(HMPtr map, char *str);
//y
void print(HMPtr map);
void destroy(HMPtr *mapPtr);
void resize(HMPtr map);
//y
unsigned int hash(char *str);
//y
unsigned int pop(HMPtr map, char *key);
//y

//|-------------------------

int main(void)
{
    HMPtr map = create();
    insert(map, "Keathan");
    insert(map, "Trey");
    insert(map, "Noah");
    insert(map, "Kleiner");
    insert(map, "data");
    insert(map, "Matthew");
    print(map);

    destroy(&map);
    return 0;
}

unsigned int pop(HMPtr map, char *str)
{
    unsigned int val = hash(str);
    size_t h = (size_t)val;
    size_t index = h % map->capacity;

    for(size_t i = 0; map->array[index].key && strcmp(str, map->array[index].key);index = (h + ((++i) + i*i)/2)%map->capacity);

    if (map->array[index].key)
    {
        map->array[index].del = true;
        return map->array[index].val;
    }

    return 0;
}

unsigned int hash(char *str)
{
    unsigned int out = 0;
    unsigned int base = 31;
    unsigned int factor = 1;

    for (size_t i = 0; str[i] != 0; ++i)
    {
        out += (unsigned int)str[i] * factor;
        factor *= base;
    }

    return out;
}

void resize(HMPtr map)
{
    NodePtr old = map->array;
    size_t old_capacity = map->capacity;
    map->capacity = old_capacity * 2;
    map->array = calloc(map->capacity, sizeof(Node));

    for(size_t i = 0; i < old_capacity; ++i)
    {
        if(old[i].key)
        {
            if(old[i].del)
                free(old[i].key);
            else
                resize_insert(map, old[i].key);
        }
    }

    free(old);
}

void resize_insert(HMPtr map, char *str)
{
    unsigned int val = hash(str);
    size_t h = (size_t)val;
    size_t index = h % map->capacity;

    for (size_t i = 0; map->array[index].key; index = (h + ((++i) + i*i)/2)%map->capacity);

    map->array[index].key = str;
    map->array[index].val = val;
    ++(map->size);
}

void insert(HMPtr map, char *str)
{
    unsigned int val = hash(str);
    size_t h = (size_t)val;
    size_t index = h % map->capacity;
    size_t i;
    NodePtr deleted = NULL;

    for(i = 0; map->array[index].key && strcmp(str, map->array[index].key);index = (h + ((++i) + i*i)/2)%map->capacity)
        if(!deleted && map->array[index].del)
        {
            deleted = map->array + index;
            for(index = (h + ((++i) + i*i)/2)%map->capacity; map->array[index].key && strcmp(str, map->array[index].key); index = (h + ((++i) + i*i)/2)%map->capacity);
            break;
        }

    if (map->array[index].key == NULL)
    {
        if(deleted)
        {
            free(deleted->key);
            deleted->del = false;
            index = deleted - map->array;
        }
        else if (++(map->size) >= 0.7*map->capacity)
        {
            resize(map);
            index = h % map->capacity;
            for (i = 0; map->array[index].key; index = (h + ((++i) + i*i)/2)%map->capacity);            
        }
        map->array[index].key = calloc(strlen(str)+1, sizeof(char));
        strcpy(map->array[index].key, str);
    }
    else 
        map->array[index].val = val;
}

HMPtr create()
{
    HMPtr newList = malloc(sizeof(HashMap));
    newList->size = 0;
    newList->capacity = INITIAL_CAPACITY;
    newList->array = calloc(newList->capacity, sizeof(NodePtr));
    return newList;
}

void destroy(HMPtr *mapPtr)
{
    free((*mapPtr)->array);
    free(*mapPtr);
    *mapPtr = NULL;
}

void print(HMPtr map)
{
    for (size_t i = 0; i < map->capacity; ++i)
        printf("%s;%u\n", map->array[i].key, map->array[i].val);
}

这是我在 gdb 上运行后收到的错误

''' 程序收到信号 SIGSEGV,分段错误。
__strcmp_sse2_unaligned()
在 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:30
30 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:没有这样的文件或 目录。 '''

如果有人能发现问题,那将有很大帮助。谢谢!

【问题讨论】:

  • 首先确保您使用调试信息构建程序(使用gcc 构建时添加-g 标志)。然后,当您在调试器中捕获崩溃时,请遍历调用堆栈 up 直到您到达您的代码。它发生在您的代码中的什么位置?
  • @Someprogrammerdude 看起来好像发生在第一个“strcmp”,插入函数的第 7 行。

标签: c


【解决方案1】:

sizeof(nodePtr) 的大小是pointer 你需要sizeof(struct Node)

HMPtr create()
{
    HMPtr newList = malloc(sizeof(HashMap));
    newList->size = 0;
    newList->capacity = INITIAL_CAPACITY;
    newList->array = calloc(newList->capacity, sizeof(*newList->array));

    return newList;
}

【讨论】:

  • @NoahDavis 这是使用指针类型别名的一个非常常见的问题。通常建议反对使用此类类型别名,以避免此类问题。
猜你喜欢
  • 1970-01-01
  • 2014-03-28
  • 2013-10-14
  • 1970-01-01
  • 2011-02-03
  • 2022-07-21
  • 2016-03-03
  • 2023-01-18
  • 2021-01-19
相关资源
最近更新 更多