C - 扩展结构数组,其中指针已存在于其中

C - Expanding an array of structs with pointers already existing inside it

我有一个这样声明的结构数组

typedef struct bucket{
    char * value; 
    char * key; 
}BUCKET;

typedef struct item{
    struct bucket * data;
    struct item * next;
    struct item * prev;
}ITEM;

typedef struct base{
    struct item * first;
}BASE;

typedef BASE *SPACE;

它非常适合我必须用它做的一切。基本上我必须在 C 中实现哈希图。我设法做到了,但我完全陷入了这个任务。我需要让用户调整哈希图的大小。

如果我想要一个大小为 5 的 hashmap,我会这样做:

SPACE *hashmap = malloc(sizeof(SPACE *) * 5);

它完全符合程序的目的。

但是,如果我尝试使用以下代码块调整它的大小:

void expandHashspace(SPACE *hashmap){
    printf("Please enter how large you want the hashspace to be.\n");
    printf("Enter a number between %d and 100. Enter any other number to exit.\n>",hashSpaceSize);
    int temp = 0;
    scanf("%d",&temp);
    if(temp>100 || temp<hashSpaceSize){
        printf("Exiting...\n");
    }
    else {
        SPACE *nw = NULL;
        nw = realloc(hashmap, sizeof(SPACE *) * temp);
        hashmap = nw;
        hashSpaceSize = temp;
        printf("Your hashspace is now %d rows long.\n", hashSpaceSize);
    }
}

它也能正常工作。但是,当我去使用 hashmap 本身时,它以分段错误结束。或者 SIGSEGV 信号 11.

比如我有如下显示功能

void displayHashspace(SPACE *hashmap){
    printf("\n");
    int j = 0;
    for(int i = 0; i < hashSpaceSize && hashmap; i++){
        BASE *linkedList = hashmap[i];
        if(linkedList) {
            ITEM *node = linkedList->first;
            printf("\n[HASH %d]\n", i);
            while (node) {
                printf("\t[BUCKET %d]\n\t[VALUE] : %s\n\t[KEY] : %s\n\n",j, node->data->value, node->data->key);
                node = node->next;
                j++;
etc...

使用CLion的调试,我意识到: 假设 hashmap 大小为 3。这意味着只有 hashmap[0-2] 存在。 如果我将 hashmap 的大小调整为,比方说 10,它允许我调整大小。 但是在显示的时候,hashmap[3]的地址真的很奇怪。 其他地址都很长,几乎有 8 位或更多,而 hashmap[3] 的地址总是 0x21

此后,一旦到达ITEM *node = linkedList->first;,linkedList为hashmap[3],就出现了segmentation fault

这是另一个例子。这是我的保存功能:

void saveHash(SPACE *hashmap){
    FILE *f = fopen("hashmap.hsh","w");
    fprintf(f,"%d\n",hashSpaceSize);
    for(int i = 0; i < hashSpaceSize;i++){
        if(hashmap[i]){
            ITEM *save = hashmap[i]->first;
            do{
                fprintf(f,"---\n%s\n%s\n",save->data->value,save->data->key);
                save = save->next;
            }while(save);
etc...

在这里,故事是不同的。它只能在调整大小后崩溃之前到达 hashmap[0]。使用调试器,我发现不知何故,设置为 hashmap[0]->first(通常在扩展之前工作)的保存有一个 BUCKET,其 VALUE 变量由于某种原因突然设置为 NULL,因此崩溃。

我尝试将扩展后的每个 "new" BASE 设置为 NULL,但在使用 expandHashspace() 后保存功能仍然中断。

我做错了什么?

将内存重新分配给 hashmap 无效,因为 hashmap 在该方法中是一个局部变量。意味着一切都变成了一场令人困惑的噩梦。

返回 hashmap 本身而不是什么都不返回解决了所有问题。