我无法制作单链表。这个链表应该收到 name,GPA,key ---生成节点---打印---取消分配内存。但是,我的代码似乎有错误。但我无法找到它们的位置。你能找到错误的代码吗?
每当我输入第二个节点的名称,GPA和密钥信息时,都会发生未处理的win32异常错误。
#include <stdio.h>
#include <stdlib.h>
struct STUDENT {
char name[20];
float GPA;
int key;
struct STUDENT *next;
};
void newnode(struct STUDENT *head, struct STUDENT *tail, struct STUDENT *preptr, struct STUDENT *curptr, int i)
{
struct STUDENT *newitem;
newitem = (struct STUDENT*)malloc(sizeof(struct STUDENT));
if (newitem == (struct STUDENT*)NULL)
{
printf("No memory space available");
}
printf("Name?\n");
gets(newitem->name);
getchar();
printf("GPA?\n");
scanf("%f", &(newitem->GPA));
getchar();
printf("Key?\n");
scanf("%d", &(newitem->key));
getchar();
if (i == 0)
{
head = newitem;
tail = newitem;
curptr = newitem;
}
else
{
preptr = curptr;
tail = newitem;
curptr = newitem;
preptr->next = newitem;
}
}
void main()
{
int i;
struct STUDENT *head = NULL; //location of the first node
struct STUDENT *tail = NULL; //location of the last node
struct STUDENT *preptr = NULL; //previous
struct STUDENT *curptr = NULL; //current
for (i = 0; i <= 9; i++)
{
newnode(head, tail, preptr, curptr, i);
}
curptr = head;
printf("name %s, GPA %f, key %d\n", curptr->name, curptr->GPA, curptr->key);
preptr = head;
curptr = curptr->next;
for (i = 0; i <= 8; i++)
{
printf("name %s, GPA %f, key %d\n", curptr->name, curptr->GPA, curptr->key);
curptr = curptr->next;
}
curptr = head;
for (i = 0; i <= 9; i++)
{
free(curptr);
curptr = curptr->next;
}
getchar();
getchar();
}
答案 0 :(得分:1)
在void newnode(struct STUDENT *head, struct STUDENT *tail, struct STUDENT *preptr, struct STUDENT *curptr, int i)
中,您正在分配和修改指针的内容(或者至少希望它们被更新),但在这种情况下,您需要将指针传递给head
,tail
,preptr
和curptr
,因为您希望更新main()
中的这些变量。
所以将newnode
的签名更改为
void newnode(struct STUDENT **head, struct STUDENT **tail, struct STUDENT **preptr, struct STUDENT **curptr, int i)
以及该函数的内容:
if (i == 0)
{
*head = newitem;
*tail = newitem;
*curptr = newitem;
}
else
{
*preptr = *curptr;
*tail = newitem;
*curptr = newitem;
(*preptr)->next = newitem;
}
并相应地调用此函数:
newnode(&head, &tail, &preptr, &curptr, i);
一般提示:
newitem = (struct STUDENT*)malloc(sizeof(struct STUDENT));
没有必要转换malloc的返回值,它返回void *
,它可以分配给任何类型的指针。
if (newitem == (struct STUDENT*)NULL)
这里也是一样的。无需投射NULL
。
if (newitem == (struct STUDENT*)NULL)
{
printf("No memory space available");
}
一旦检测到内存分配存在问题,最好在打印错误消息后从该功能返回。否则,您的代码将继续在该函数内运行,访问未分配的struct字段。
gets(newitem->name);
使用gets
是不安全的,因为您的缓冲区(name
)限制为20,但如果gets
将获得100个字符的字符串,则会将它们全部存储在{{ 1}}覆盖超出name
内存的所有内容,导致未定义的行为。
name
此代码不正确。因为您首先免费for (i = 0; i <= 9; i++)
{
free(curptr);
curptr = curptr->next;
}
然后访问其字段。您应首先将curptr
保存在某个时态变量curptr->next
中,然后免费temp = curptr->next
,然后重新定位curptr