单向链表创建过程中的异常

Exception during singly linked list creation

我在制作单向链表时遇到问题。这个链表应该收到 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();
}

void newnode(struct STUDENT *head, struct STUDENT *tail, struct STUDENT *preptr, struct STUDENT *curptr, int i)中你正在分配和修改指针的内容(或者至少你希望它们被更新)但是在那种情况下你需要将指针传递给headtailpreptrcurptr 因为您希望更新 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 的 returned 值转换为 returns void *,它可分配给任何类型的指针。

if (newitem == (struct STUDENT*)NULL)

这里也是一样。无需投 NULL.

if (newitem == (struct STUDENT*)NULL)
{
    printf("No memory space available");
}

一旦您检测到内存分配存在问题,您最好在打印错误消息后从该函数 return。否则,您的代码将继续 运行 在该函数内访问未分配的结构字段。

gets(newitem->name);

使用 gets 是不安全的,因为您的缓冲区 (name) 被限制为 20,但是如果 gets 将得到一个 100 个字符的字符串,它将把它们全部存储在name 覆盖超出 name 内存的所有内容导致未定义的行为。

for (i = 0; i <= 9; i++)
{
    free(curptr);
    curptr = curptr->next;
}

此代码不正确。因为您首先释放 curptr 然后访问它的字段。您应该首先将 curptr->next 保存在某个时间变量 temp = curptr->next 中,然后释放 curptr 然后重新分配它 curptr = temp;