在分配新结构时遇到问题
Having issues allocating a new struct
我在这里阅读了六个与此相关的答案,我比较不愿意问这样的问题,但我正在尝试使用 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
我遇到的问题是第二个列表显然覆盖了第一个或类似列表,而且我的指针功能很弱,我需要做什么才能成功分配新结构?
查尔斯·B.
你 return 一个指向局部变量的指针,一旦函数 returns 局部变量就超出范围,这给你留下了一个杂散的指针。使用该杂散指针将导致未定义的行为。
问题始于 curElement
的声明,编译器真的应该为此对你大喊大叫:
cell curElement = (cell *) malloc(sizeof(cell));
在这里声明 curElement
是一个实际的结构,而不是指向该结构的指针。
还有一个问题是您实际上没有 end 列表。您分配添加的最后一个节点的 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
函数的 return 值与 [=16 进行比较=],因为 fscanf
(和系列)将 return 成功解析的项目数,这允许您在输入文件中查找格式错误。
第二个变化是不施放 malloc
的 return。在 C 中,你永远不应该从 void *
转换或转换到 void *
,这样的转换可以隐藏细微的错误。
我在这里阅读了六个与此相关的答案,我比较不愿意问这样的问题,但我正在尝试使用 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
我遇到的问题是第二个列表显然覆盖了第一个或类似列表,而且我的指针功能很弱,我需要做什么才能成功分配新结构?
查尔斯·B.
你 return 一个指向局部变量的指针,一旦函数 returns 局部变量就超出范围,这给你留下了一个杂散的指针。使用该杂散指针将导致未定义的行为。
问题始于 curElement
的声明,编译器真的应该为此对你大喊大叫:
cell curElement = (cell *) malloc(sizeof(cell));
在这里声明 curElement
是一个实际的结构,而不是指向该结构的指针。
还有一个问题是您实际上没有 end 列表。您分配添加的最后一个节点的 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
函数的 return 值与 [=16 进行比较=],因为 fscanf
(和系列)将 return 成功解析的项目数,这允许您在输入文件中查找格式错误。
第二个变化是不施放 malloc
的 return。在 C 中,你永远不应该从 void *
转换或转换到 void *
,这样的转换可以隐藏细微的错误。