从指针链接列表中删除节点

时间:2016-04-05 09:18:37

标签: c linked-list

我有一个程序可以将学校课程添加到链接列表中。我可以将课程添加到列表中并打印出来。

但是我无法从链接列表中删除课程(remove_course函数)。由于某种原因,我传入delete_from_list的CourseList等于NULL。

的main.c

#define _CRT_SECURE_NO_WARNINGS

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "bst.h"
#include "courseList.h"

/* Add course to the given linked list */
void add_course(CourseList *self)
{
    char course_name[100];
    Course *c;

    printf("enter a course name: \n");
    scanf("%s", course_name);

    c = (Course*)malloc(sizeof(struct course));

    c->name = (char*)malloc(strlen(course_name) + 1);
    strcpy(c->name, &course_name);
    c->students = NULL;

    insert_at_front(self, *c);
}

/* Remove a given course from the given linked list */
void remove_course(CourseList *self)
{
    char course_name[100];
    printf("What course would you like to remove?\n");
    scanf("%s", course_name);
    delete_from_list(self, course_name);
}

/* Print the courses in the given linked list */
void print_courses(CourseList *self)
{
    CourseList current;
    current = *self;
    printf("Your list is: \n");
    while (current != NULL) 
    {   
        printf("%s\n", current->data.name); 
        current = current->next; 
    }
    printf("\n");    
}      

int main(void)
{       
    CourseList master;    
    int choice;

    printf("Welcome to student enrolment\n");

    while (true)
    { 
        printf("Pick your option\n");
        scanf("%d", &choice);
        switch (choice)
        {
        case 0:
            exit(1);
            break;
        case 1:
            add_course(&master);
            printf("%s was add to the list!\n", master->data.name);
            break;
        case 2:
            print_courses(&master);
            break;
        case 3:
            remove_course(&master);
            break;
        }    
    }    
}

CourseList.c

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "bst.h"
#include "courseList.h"


void insert_at_front(CourseList *cl, Course c)
{
    CourseList newNode;

    newNode = (CourseList)malloc(sizeof(struct courseNode));
    newNode->data = c;
    newNode->next = *cl;

    *cl = newNode;    
}    

void delete_from_list(CourseList *self, char *course_name)
{
    CourseList current = *self;
    CourseList prev = NULL;
    CourseList to_free = NULL;

    while (current != NULL)
    {
        if (strcmp(current->data.name, course_name) == 0) //Error here current has nothing in it
        {
            if (prev == NULL)
            {
                *self = current->next;
                free(current);
                current = *self;
            }
            else
            {
                prev->next = current->next;
                free(current);
                current = prev->next;
            }
        }
        else
        {
            prev = current;
            current = current->next;
        }
    }
}

CourseList.h

#include "bst.h"

#ifndef COURSELIST_H
#define COURSELIST_H

struct course;
typedef struct course Course;

struct courseNode;
typedef struct courseNode *CourseList;

typedef struct course
{
    char *name;
    BST students;

} Course;

typedef struct courseNode
{
    Course data;
    struct courseNode *next;

} *CourseList;

void insert_at_front(CourseList *cl, Course c);
void delete_from_list(CourseList *self, char *course_name);

#endif

bst.h

#ifndef BST_H
#define BST_H

typedef struct bstNode
{
    long student_id;
    struct bstNode*left;
    struct bstNode*right;

} *BST;

#endif

1 个答案:

答案 0 :(得分:2)

您永远不会在master函数中初始化变量main。这意味着它将具有 indeterminate 值,并且使用它未初始化将导致未定义的行为

您需要将其初始化为NULL指针:

CourseList master = NULL;

当您没有初始化变量时,现在发生了什么,是insert_at_front函数中的

newNode->next = *cl;

由于来自*cl的{​​{1}}为master,并且它未初始化,它将具有看似随机的值,很可能不是main,并且因此看起来新节点将在列表中有一个下一个节点,而实际上并没有。

这会导致NULL中的循环继续经过列表中的实际最后一个节点,并且您将取消引用不属于您已分配的任何节点或数据的数据。