单链表创建期间的例外情况

时间:2015-10-03 16:34:59

标签: c pointers singly-linked-list

我无法制作单链表。这个链表应该收到 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();
}

1 个答案:

答案 0 :(得分:1)

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的返回值,它返回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