C语言 无法迭代带有 while(1) 循环的双向链表 - 分段错误



我第一次来这里,也是初学者,所以请耐心等待。

我得到了一个处理双向链表的任务,我们得到了两个打印函数,可以向前和反向打印链表。 无论如何,我们都不允许更改这些功能。

我无法通过传递链表while(1)传递给它。我做了一个测试函数,它用while(pointer != NULL)迭代列表并且工作正常。

有什么建议吗?

这是我的主要功能。

FILE *fp;
struct node{
int data;
struct node* prev;
struct node* next;
};
typedef struct node* listPointer;
listPointer headNode = NULL;
listPointer tailNode = NULL;

void delete(listPointer *head, listPointer removalNode);
//int traverseList(listPointer head, int data);
listPointer insertBefore(listPointer *head, listPointer nextNode, listPointer insertionNode);
listPointer findPosition(listPointer *head, int data);
listPointer findNode(listPointer *head, int data);
listPointer insertAtHead(listPointer *head, listPointer insertionNode);
listPointer insertAtBack(listPointer *head, listPointer insertionNode);
listPointer createNode(int data);
void print_forward(listPointer list);
void print_reverse(listPointer list);
void sortedInsert(listPointer *head,listPointer *tail,int data)
{
listPointer p = malloc(sizeof(listPointer));
listPointer temp = malloc(sizeof(listPointer));
p->data = data;
p->next = NULL;
if ((*head) == NULL)
{
(*head) = p;
(*tail) = p;
(*head)->prev = NULL;
return;
}
if ((p->data) < ((*head)->data))
{
p->prev = NULL;
(*head)->prev = p;
p->next = (*head);
(*head) = p;
return;
}
if ((p->data) > ((*tail)->data))
{
p->prev = (*tail);
(*tail)->next = p;
(*tail) = p;
return;
}
temp = (*head)->next;
while ((temp->data) < (p->data))
temp = temp->next;

(temp->prev)->next = p;
p->prev = temp->prev;
temp->prev = p;
p->next = temp;
}
///test print function
void printlist(listPointer head) // this is a test function
{
listPointer temp = head;
while(temp != NULL) // works, but seg fault when is set to while(1) like line 282
{
printf("%d - ", temp->data);
temp = temp->next;
}
printf("n");
}
test print function reverse
void printlist2(listPointer head)
{
listPointer temp = head;
while( temp != NULL)
{
printf("%d - ", temp->data);
temp = temp->prev;
}
printf("n");
}

void main(int argc, char** argv)
{
if(argc != 2)
{
fprintf(stderr, "usage: ./mp1 input_filenamen");
exit(1);
}
FILE *fp = fopen(argv[1], "r");
if(fp == NULL)
{
fprintf(stderr, "The input file does not exist.n");
exit(1);
}
char *op;
listPointer temp;
listPointer newnode;
int data=0;
int flag=0;
char c;
int num;
///////////////////////////////////////////////////////// TESTING
data = 10;
op = "INSERT";
sortedInsert(&headNode,&tailNode,data);
sortedInsert(&headNode,&tailNode,6);
sortedInsert(&headNode,&tailNode,7);
printlist(headNode);
printf("nhead %dn",headNode->data);
printf("tail %dn",tailNode->data);
printlist2(tailNode);
print_forward(headNode); // seg fault
///////////////////////////////////////////////////////// TESTING

/*while(!feof(fp)){
fscanf(fp,"%s",op);
fscanf(fp,"%d",&data);
//printf("%s ",op);
//printf("%d ",data);
if(strcmp(op,"INSERT")==0){flag=1;}
else if(strcmp(op,"DELETE")==0){flag=2;}
else if(strcmp(op,"ASCEND")==0) {flag=3;}
else if(strcmp(op,"DESCEND")==0) {flag=4;}
switch(flag)
{
case 1:
newnode = createNode(data);
if(headNode == NULL) insertAtHead(&headNode,newnode);
else{
temp = findPosition(&headNode,data);
insertBefore(&headNode,temp,newnode);
}
break;
case 2:
temp = findNode(&headNode,data);
delete(&headNode,temp);
break;
case 3:
print_forward(headNode);
break;
case 4:
print_reverse(headNode);
break;
default: break;
}
}*/
fclose(fp);
}

这是给定的打印功能。

void print_forward(listPointer list) {
listPointer curr;
FILE *outfile;
outfile = fopen("mp1_result.txt", "a");
if(list) {
curr = list;
while(1) {
fprintf(outfile, "%d ", curr->data);
printf("%d ", curr->data);
curr = curr->next;
if(curr == list) break;
}
}
fprintf(outfile, "n");
printf("n");
fclose(outfile);
}
void print_reverse(listPointer list) {
listPointer curr;
FILE *outfile;
outfile = fopen("mp1_result.txt", "a");
if(list) {
curr = list->prev;
while(curr != list) {
fprintf(outfile, "%d ", curr->data);
printf("%d ", curr->data);
curr = curr->prev;
}
fprintf(outfile, "%d ", curr->data);
printf("%d ", curr->data);
}
fprintf(outfile, "n");
printf("n");
fclose(outfile);

欢迎和赞赏任何建议!

给定的函数假设一个循环的双向链表,查看检查if(curr==list)- 它检查第一个条目,而不是 NULL。由于链表不是循环的,因此在指向 NULL 时会失败。

导致您在这里出现段错误的主要原因是print_forward函数需要一个循环链表,其中头部和尾部也链接在一起。否则,while(1)循环在到达列表末尾时将出现段错误(如您所见(。

通常,一个好主意是逐个构建应用程序,边走边检查每个位,而不是一次检查整个事情,然后试图找出整个事情的问题,尤其是当你是新手时。也就是说,我可以看到您的代码存在许多问题:

  • listPointer p = malloc(sizeof(listPointer));- 这只做了它所说的:为指向列表(元素(的指针分配空间,它不会为实际的列表元素腾出空间。
  • 当您检查新项目是否大于尾部时,应使用>=。否则,如果新元素等于尾部,它将无法通过此检查,然后通过循环搜索位置,并最终在它从列表末尾掉落时出现段错误。
  • 您实际上不需要测试新项目是否小于头部 - 只需检查它是否大于(或等于(尾部,如果没有,则遍历列表中的所有项目以查找哪个大于新项目(从头部开始(。

最新更新