C-指针SEG故障,尽管我是正确的



我不明白为什么我的程序SEG故障在此行:if ((**table->table).link == NULL){我似乎对此有malloc-edmem内存,我尝试使用GDB查看它。*table->table是可访问的,而不是null,但是**table->table无法访问。hash_t的定义:

struct table_s  {   
    struct node_s **table;
    size_t bins;    
    size_t size;
};
typedef struct table_s *hash_t;
void set(hash_t table, char *key, int value){
    unsigned int hashnum = hash(key)%table->bins;
    printf("%d n", hashnum);
    unsigned int i;
    for (i = 0; i<hashnum; i++){
        (table->table)++;
    }
    if (*(table->table) == NULL){
        struct node_s n = {key, value, NULL};
        struct node_s *np = &n;
        *(table->table) = malloc(sizeof(struct node_s));
        *(table->table) = np;
    }else{
        while ( *(table->table) != NULL){
        if ((**table->table).link == NULL){
            struct node_s n = {key, value, NULL};
            struct node_s *np = &n;
            (**table->table).link = malloc(sizeof(struct node_s));
            (**table->table).link = np;
            break;
        }else if (strcmp((**table->table).key, key) == 0){
            break;
        }
            *table->table = (**(table->table)).link;
        }
        if (table->size/table->bins > 1){
            rehash(table);
        }
    }
}

我从这里打电话:

  for (int i = 0; i < trials; i++) {
     int sample = rand() % max_num;
     sprintf(key, "%d", sample);
     set(table, key, sample);
  }

您的标签作品如下:您有bins垃圾箱,每个垃圾箱都是键/值对的链接列表。垃圾箱中的所有项目都共享相同的哈希代码模型。

创建或初始化哈希表时,您可能已经创建了垃圾箱表,类似的东西:

table->table = malloc(table->bins * sizeof(*table->table);
for (size_t i = 0; i < table->bins; i++) table->table[i] = NULL;

现在为什么会员table有两颗星?

  • "内在"星是指桌子将指针存储在节点上,而不是节点本身。
  • "外部"开始是分配内存的手柄。如果您的哈希表尺寸固定,例如始终使用256个垃圾箱,则可以将其定义为:

    struct node_s *table[256];
    

    如果您通过此数组,它将变成(或"衰减")指向其第一个元素的指针,即struct node_s **,就像您从malloc中获得的数组一样。

  • 您可以通过链接列表访问L´BINS的内容,而链接列表的负责人itable->table[i]

您的代码还有其他问题:

  • 您想用(table->table)++实现什么?这将使分配的内存点的句柄不是第一个元素,而是下一个元素。完成此操作后,*table->table现在将处于正确的节点,但是您将丢失原始手柄,您必须保留,因为当您清理哈希表时,必须稍后将其传递给free。不要失去分配的内存!改用另一个本地指针。

  • 您创建一个本地节点n,然后在链接列表中使用指向该节点的指针进行链接。但是节点n将在您离开功能后将消失,链接将是"陈旧":它将指向无效的内存。您还必须使用malloc为节点创建内存。

您的有表格的简单实现可能是:

void set(hash_t table, char *key, int value)
{
    unsigned int hashnum = hash(key) % table->bins;
    // create (uninitialised) new node
    struct node_s *nnew = malloc(sizeof(*nnew));
    // initialise new node, point it to old head
    nnew->key = strdup(key);
    nnew->value = value;
    nnew->link = table->table[hashnum];
    // make the new node the new head
    table->table[hashnum] = nnew;
}

这使新节点成为链接列表的头部。这不是理想的选择,因为如果您覆盖项目,将找到新项目(很好),但是旧的项目仍然在桌子中(这不好)。但是,正如他们所说,这是读者的练习。

strdup函数不是标准的,而是广泛可用。它还创建了新的内存,您必须以后释放,但是它可以确保字符串" live"(仍然有效)在您结核哈希表之后。)

请不要在代码中有几颗星星。如果一颗恒星太少,它在hash_t中,您已经输入了指针性质。

相关内容

  • 没有找到相关文章

最新更新