如何获取链表指针的地址,以便在删除c中的一项后在哈希表中正确设置它?

如何获取链表指针的地址,以便在删除c中的一项后在哈希表中正确设置它?,c,pointers,C,Pointers,从哈希表中删除元素时,我需要遍历发生冲突的元素的链接列表。我使用指针操作来实现这一点,我的链表是bucket\t的形式。我面临的问题是,当我试图保存第一个ht->bucket[I]的位置时,该值会随着其他值的变化而变化,因此在函数结束时,我的头正好位于next的位置,并导致分段错误。我对在c中使用这样的指针还不熟悉,如果我的解释不好,我很抱歉,但我认为代码非常简单,你们可以看到我试图实现的目标: void ht_del(hashtable_t *ht, char *key) { bucket_

从哈希表中删除元素时,我需要遍历发生冲突的元素的链接列表。我使用指针操作来实现这一点,我的链表是
bucket\t
的形式。我面临的问题是,当我试图保存第一个
ht->bucket[I]
的位置时,该值会随着其他值的变化而变化,因此在函数结束时,我的头正好位于
next
的位置,并导致分段错误。我对在c中使用这样的指针还不熟悉,如果我的解释不好,我很抱歉,但我认为代码非常简单,你们可以看到我试图实现的目标:

void  ht_del(hashtable_t *ht, char *key) {
bucket_t *last=NULL, *next=NULL, *head=NULL;
unsigned long i;
for(i = 0; i < ht->size; i++){
  head = ht->buckets[i];
  next = ht->buckets[i];
  while(next && next->key && strcmp(next->key,key)!=0){
    last = next;
    next = next->next;
    printf("\nvisiting next\n");
    printf("key = %s\n", head->key);
  }
  if(next && next->key && strcmp(next->key,key)==0){
    printf("key found, removing key = %s, val = %s:", next->key, next->val);
    free(next->key);
    free(next->val);
    if(next->next){
      last->next = next->next;
      printf("Last->next ->key = %s\n", last->next->key);
    }
    else{
      free(next->next);
      printf("end of the line\n");
    }
    free(next);
    printf("head key = %s", head->key);
  }
 }
}
如何获取链接列表指针的地址,以便在删除某个项后在哈希表中正确设置它

要从链接列表中删除节点,请跟踪上一个节点


为什么要用
printf(“key=%s\n”,head->key”)重复打印
head
while()
循环中的code>?我这样做只是想看看在遍历链表时它是否在变化。嗯,假设
while(…&&strcmp(next->key,key)!=0)
第一次失败,因为字符串比较相等<代码>如果(…&&strcmp(下一步->键,键)==0)
将通过,稍后代码将通过
如果(下一步->下一步){
。如果这是真的,那么代码会
NULL->next=…
,这是一个问题。我没有看到。很可能是其他代码中存在问题。嗯,这一点很好。我对此进行了快速修复,但这并没有停止问题。我面临的问题是,当我上下移动时,它也会移动ht->bucket[I].因此,无论使用不同的变量,我的头都会不断移动,最终会被删除。这是对代码的极大改进,也是哈希而不是for循环的一大优点,谢谢你们。但是,我仍然有同样的问题,因为我仍然在同一个位置出现分段错误,因为ht->bucket[I]被移动,并最终被删除。@LucasTrestka可能发布了足够多的可编译代码,添加到HT,从HT删除,然后是seg错误。我找到了解决方案,您的代码很好,唯一需要做的就是将HT->Bucket[I]=previous->next设置为代码的最后一行。@LucasTrestka我对
HT->Bucket[I]有疑问=前一次>下一次>代码>我想我的更新修复了这个问题。如果你还有问题,请告诉我。次要:更好地使用<代码> SigZiTi;<代码> > <代码>未签名的长i; HTT>大小<代码>是素数。
typedef struct hashtable hashtable_t;
typedef struct bucket bucket_t;

struct bucket {
  char *key;
  void *val;
  bucket_t *next;
};

struct hashtable{
  unsigned long size;
  bucket_t **buckets;
};
for(i = 0; i < ht->size; i++){
  bucket_t before_head = { .next = ht->buckets[i] };  // Only next member used.
  bucket_t *previous = &before_head;
  while (previous->next && strcmp(previous->next->key,key) != 0) {
    previous = previous->next;
  }
  if (previous->next) { // match was found
    // delete previous->next and its members allocations
    bucket_t *node_after_match = previous->next->next;
    free(previous->next->key);
    free(previous->next->val);
    free(previous->next);
    // link previous to node after deletion.
    previous->next = node_after_match; 

    // assign a potential new head of the list
    ht->buckets[i] = before_head.next;
    break; // exit for loop  
  }
}
// for(i = 0; i < ht->size; i++){
i = hash(key)%ht->size;
void  ht_del(hashtable_t *ht, char *key) {
    unsigned long i;
    i = hash(key)%ht->size;
    bucket_t before_head = { .next = ht->buckets[i]};
    bucket_t *previous = &before_head;
    while(previous->next && strcmp(previous->next->key,key)!=0) {
      previous = previous->next;
    }
    if(previous->next ) {
      bucket_t *next = previous->next->next;
      bucket_t *b = previous->next;
      free(previous->next->key);
      free(previous->next->val);
      previous->next = next;
      free(b);
      ht->buckets[i] = previous->next;
    }
}