我已经在这里阅读了六个关于此问题的答案,并且相对不愿问这样的问题,但是我试图使用C中的结构创建一个链表,并且正在尝试将指针传递给链表时出现问题。我认为它主要是排序的,但老实说,我正在努力让链表工作。
#include <stdio.h>
#include <stdlib.h>
typedef struct cell
{
int value;
struct cell *next;
} cell;
int inputplace = 0;
cell * createlist()
{
cell curElement = (cell *) malloc(sizeof(cell));
cell *head = &curElement;
cell *curEl = &curElement;
curEl->value = 900;
FILE *fp;
char *mode = "r";
fp = fopen("input",mode);
if(fp==NULL)
{
fprintf(stderr, "Unable to open input file 'input'");
exit(1);
}
int val;
int tempplace = 0;
while(tempplace < inputplace)
{
if(fscanf(fp, "%d", &val) != EOF)
{
tempplace++;
printf("%d", &val);
}
else
break;
}
while(fscanf(fp, "%d", &val)!=EOF)
{
inputplace++;
printf("%d\n", curEl);
if(val < 0)
{
curEl->value = -1;
curEl->next = -1;
break;
}
printf("%d\n", val);
curEl->value = val;
curEl->next = malloc(sizeof(struct cell));
curEl= curEl->next;
}
return head;
}
cell* reverse(cell* p)
{
cell * prev = -1;
cell * current = p;
cell * next;
while(current->value != -1)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
cell* append(cell* p, cell* q)
{
cell * current = p;
cell * r = p;
while(1)
{
if(current->value == -1)
{
current->value = q->value;
current->next = q->next;
}
}
return r;
}
int last(cell *p)
{
cell q = *p;
int last = -1;
while(1)
{
if(q.value == -1)
{
return last;
}
else
{
last = q.value;
q = *q.next;
}
}
}
cell * delete(int n, cell *p)
{
cell * head = p;
cell * prev = -1;
cell * current = p;
if(current-> value == n)
{
return current->next;
}
else
{
while(current->value != -1)
{
if(current->value==n)
{
prev->next = current->next;
break;
}
prev = current;
current = current->next;
}
}
return head;
}
int member(int n, cell *p)
{
cell q = *p;
while(1)
{
if(q.value == n)
{
return 1;
}
if(q.value == -1)
{
return 0;
}
q = *q.next;
}
}
int display(cell *p)
{
printf(" %c", '[');
cell q = *p;
while(1)
{
if(q.value == -1)
{
printf("%c ",']');
return 1;
}
if(q.next != p->next)
printf("%c ",',');
printf("%d", q.value);
q = *q.next;
}
printf("\n\n");
}
int main()
{
cell *head = createlist();
cell *headk = createlist();
cell *head3 = delete(5, head);
printf("%d, %d\n", head->value, head->next->value);
printf("Last head: %d\n", last(head));
display(headk);
display(head);
display(head3);
cell *head4 = delete(6, head);
display(head4);
cell *head5 = delete(7, head);
display(head5);
printf("Member2 6, head: %d\n", member(6,head));
printf("Member2 3, head: %d\n", member(3, head));
cell *head2 = reverse(head);
//print(head2);
printf("%d, %d\n", head2->value, head2->next->value);
}
因此输入文件包含终止列表的否定数字数据:
示例输入我使用:
5
6
7
-1
1
2
3
-1
我遇到的问题是第二个列表显然是覆盖了第一个或者一些这样的,并且我的指针是弱的,我需要做什么才能成功分配新的结构?
Charles B.
答案 0 :(得分:2)
返回指向局部变量的指针,一旦函数返回,局部变量就会超出范围,并且会留下一个迷路指针。使用该迷路指针将导致未定义的行为。
问题始于curElement
的声明,编译器应该真的为此尖叫:
cell curElement = (cell *) malloc(sizeof(cell));
在这里,您将curElement
声明为实际结构,而不是指向结构的指针。
还有一个问题是你没有结束到列表中。您分配了添加的最后一个节点的next
指针,无论是否有下一个节点,并且您没有初始化该节点,因此您分配的内存将是未初始化的,并尝试访问它将导致另一种未定义的行为。
我建议使用以下缩写代码:
cell *head = NULL;
cell *tail = NULL;
...
while (fscanf(fp, "%d", &val) == 1)
{
...
cell *current = malloc(sizeof(*current));
current->val = val;
current->next = NULL; // Very important!
// Check if this is the first node in the list
if (head == NULL)
head = tail = current;
else
{
// List is not empty, append node to end of list
tail->next = current;
tail = current;
}
}
除了处理和添加列表的方式发生变化之外,还有另外两个变化:第一个是将fscanf
函数的返回值与1
进行比较,因为{{ 1}}(和family)将返回成功解析的项目数,这允许您在输入文件中查找格式错误。
第二个变化是不投出fscanf
的回报。在C中,你不应该从malloc
投射或投射到void *
,这样可以隐藏微妙的错误。