C 我的链表怎么了?

C 我的链表怎么了?,c,linked-list,segmentation-fault,C,Linked List,Segmentation Fault,当我试图从main向列表中插入一个元素时,我遇到了一个分段错误。 是什么导致分段错误?如果您需要更多信息,如structs的定义,请告诉我 编辑:我意识到我做了什么。在allocate内部,我更改了局部变量列表的地址。这意味着myList没有发生任何事情。然而,现在我遇到了以下难题:我将myList的声明置于main之外,一切正常: void uf_list_allocate(struct uf_list *list) { list = malloc(sizeof(struct uf_lis

当我试图从
main
向列表中插入一个元素时,我遇到了一个分段错误。 是什么导致分段错误?如果您需要更多信息,如
structs
的定义,请告诉我

编辑:我意识到我做了什么。在
allocate
内部,我更改了局部变量
列表的地址。
这意味着
myList
没有发生任何事情。然而,现在我遇到了以下难题:我将
myList的声明置于
main之外,
一切正常:

void uf_list_allocate(struct uf_list *list)
{
  list = malloc(sizeof(struct uf_list));
  if(list == NULL)
    {fprintf(stderr, "no memory for allocate");}
  list->head = list->tail = NULL;
}
//--------------------------------------------------------------------------------------
void insert_node(struct uf_list *list, const char label)   
{
  struct uf_node *it = malloc(sizeof(struct uf_node));
  if(it == NULL)
    {fprintf(stderr, "no memory for insert");}

  it->c = label;
  it->next = NULL;                                     
  it->rep = NULL;

  if(list->head == NULL)                                //the list is empty
    { list->head = list->tail = it;}
  else
    { list->tail->next = it; list->tail = it; }

  it->rep = list->head;
}
/*----------------------------------------------------------------------------*/
struct uf_node
{
  char c;
  struct uf_node *next;
  struct uf_node *rep;
};
/*----------------------------------------------------------------------------*/
struct uf_list
{
  struct uf_node *head;
  struct uf_node *tail;
};

我不太明白为什么。似乎应该应用相同的逻辑,也就是说,由于我将
myList
的地址传递到allocate,但随后更改局部变量
list
address并对该地址进行操作,这如何反映在内存地址未被操作的
myList
上?

在allocate中,您不会返回任何内容。这就是问题所在。大体上,您应该只有一个指针作为局部变量,并将分配器函数返回的内容分配给它

编辑

更简单的是,因为它已经被分配(在main的堆栈上),所以您可以从该函数中删除分配代码,并拥有一个初始化函数。 这就是您所需要的:

struct uf_list myList;

int main(int argc, char *argv[])
{
  printf("successfully started main\n");
  uf_list_allocate(&myList);
  printf("successfully allocated myList\n");
  insert_node(&myList, 'c');
  insert_node(&myList, 'd');
  insert_node(&myList, 'e');
  printf("successfully inserted into myList\n");
  print_uf_list(&myList); 


  return 0;
} 
在原始代码中:

  Uf_list_init(struct uf_list *list)
 {
    list->head = list->tail = NULL;
 }

您有一个指向te struct的指针,但您用一个全新的指针覆盖它。

C按值传递参数
uf\u list\u allocate
应采用
uf\u list**listRef
进行修改

list = malloc(sizeof(struct uf_list));
#包括
#包括
结构uf_节点
{
字符c;
结构uf_节点*next;
结构uf_节点*rep;
};
结构uf_列表
{
结构uf_节点*头部;
结构uf_节点*tail;
};
无效用友列表分配(结构用友列表**listRef)
{
*listRef=malloc(sizeof(struct uf_list));
如果(*listRef==NULL)
{fprintf(stderr,“没有内存分配”);退出(0);}
(*listRef)->head=(*listRef)->tail=NULL;
}
void insert_节点(结构uf_列表*列表,常量字符标签)
{
struct uf_node*it=malloc(sizeof(struct uf_node));
if(it==NULL)
{fprintf(stderr,“插入时没有内存”);退出(0);}
it->c=标签;
it->next=NULL;
it->rep=NULL;
if(list->head==NULL)//列表为空
{list->head=list->tail=it;}
其他的
{list->tail->next=it;list->tail=it;}
it->rep=list->head;
}
int为空(const struct uf_list*list)
{
返回列表->头==NULL;
}
void remove_节点(结构uf_列表*列表)
{
如果(是空的(列表))
{
printf(“列表下溢”);退出(0);
}
其他的
{
结构uf_节点*oldhead=list->head;
列表->标题=列表->标题->下一步;
如果(列表->尾部==旧头部)
list->tail=NULL;
免费(旧头);
printf(“已删除节点”);
}
}
无效解除分配(结构uf_列表**listRef)
{
结构uf_list*list=*listRef;
如果(!为空(列表))
{
而(!为空(列表))
删除_节点(列表);
}
免费(名单);
列表=空;
printf(“列表解除分配\n”);
}
无效打印列表(常量结构uf_列表*myList)
{
结构uf_节点*cur=myList->head;
while(cur!=NULL)
{
printf(“%c->”,cur->c);
cur=cur->next;
}
printf(“\n”);
}
int main(int argc,char*argv[])
{
printf(“已成功启动主\n”);
结构uf_列表*myList;
uf\u列表\u分配(&myList);
printf(“已成功分配myList\n”);
插入_节点(myList,'c');
printf(“成功地将c插入myList\n”);
插入_节点(myList,'d');
printf(“成功地将d插入myList\n”);
打印列表(myList);
插入_节点(myList,'e');
printf(“成功地将e插入myList\n”);
打印列表(myList);
删除_节点(myList);
printf(“已成功从myList中删除c(头)\n”);
打印列表(myList);
取消分配(&myList);
返回0;
}

-1:你有1.2k代表,你肯定知道不先做一些基本调试就询问seg故障的问题更好。我到处都放了一堆打印语句,运气不好。。。我很少用C语言编程,我做的大部分事情都是用高级语言。我觉得这里的一切都合乎逻辑。我不知道还能做些什么…请仔细看看最后执行的一行可能是什么?列表结构的声明在哪里?问题很可能是从您没有发布的uf_list_allocate()开始的。顺便说一句,如果malloc失败,代码不应该继续。这是一个双链接列表,对吗?所以
it->rep
应该指向上一个节点,而不是
list->head
?它是main的堆栈变量,不能修改它的地址当然,你也应该在main中进行适当的更改。我刚刚将
myList
的声明放在main之外,它就工作了。为什么?全局变量在数据段中分配是否正确?您不能在函数中修改
myList
,除非它是全局变量或通过引用传递。我在
删除节点
(删除头部节点)、
取消分配
(清空并取消分配整个列表)中添加了一些代码,还有一些示例。这使它更清楚一点。希望你现在就明白了。我正在发布整个代码-
insert\u节点
没有变化,只是如果
malloc
失败,它会中止执行。等等,我传递了
myList
的地址,所以为什么我不能更改
head
tail
的值?我不记得很清楚,但这可能是标准的一部分,你可以用谷歌搜索它。但堆栈上的变量肯定不会自动初始化为任何值,它们只是开始使用随机位填充。是的,发现它还注意到,空指针不要求等于零,因此依赖包含空指针的零填充内存不是严格可移植的,会影响最佳实践。所以请不要依赖它来学习C。无论如何,依赖它是非常糟糕的做法,分配并不是完全多余的,以这种方式消除它是一个丑陋的黑客行为。
list = malloc(sizeof(struct uf_list));
#include <stdio.h>
#include <stdlib.h>

struct uf_node
{
  char c;
  struct uf_node *next;
  struct uf_node *rep;
};

struct uf_list
{
  struct uf_node *head;
  struct uf_node *tail;
};

void uf_list_allocate(struct uf_list **listRef)
{
  *listRef = malloc(sizeof(struct uf_list));
  if(*listRef == NULL)
    {fprintf(stderr, "no memory for allocate"); exit(0);}
  (*listRef)->head = (*listRef)->tail = NULL;
}

void insert_node(struct uf_list *list, const char label)
{
  struct uf_node *it = malloc(sizeof(struct uf_node));
  if(it == NULL)
    {fprintf(stderr, "no memory for insert"); exit(0);}

  it->c = label;
  it->next = NULL;
  it->rep = NULL;

  if(list->head == NULL)                                //the list is empty
    { list->head = list->tail = it;}
  else
    { list->tail->next = it; list->tail = it; }

  it->rep = list->head;
}

int is_empty(const struct uf_list *list)
{
  return list->head == NULL;
}

void remove_node(struct uf_list *list)
{
  if (is_empty(list))
  {
    printf("List underflow\n"); exit(0);
  }
  else
  {
    struct uf_node *oldhead = list->head;
    list->head = list->head->next;
    if (list->tail == oldhead)
      list->tail = NULL;
    free(oldhead);
    printf("Node removed\n");
  }
}

void deallocate(struct uf_list **listRef)
{
  struct uf_list *list = *listRef;
  if(!is_empty(list))
  {
    while(!is_empty(list))
      remove_node(list);
  }
  free(list);
  list = NULL;
  printf("List deallocated\n");
}

void printList(const struct uf_list *myList)
{
  struct uf_node *cur = myList->head;
  while(cur!=NULL)
  {
    printf("%c -> ", cur->c);
    cur = cur->next;
  }
  printf("\n");
}

int main(int argc, char *argv[])
{
  printf("successfully started main\n");
  struct uf_list *myList;
  uf_list_allocate(&myList);
  printf("successfully allocated myList\n");

  insert_node(myList, 'c');
  printf("successfully inserted c into myList\n");

  insert_node(myList, 'd');
  printf("successfully inserted d into myList\n");
  printList(myList);

  insert_node(myList, 'e');
  printf("successfully inserted e into myList\n");
  printList(myList);

  remove_node(myList);
  printf("successfully removed c (head) from myList\n");
  printList(myList);

  deallocate(&myList);

  return 0;
}