2016-04-05 3 views
0

У меня есть программа, которая добавляет школьные курсы в связанный список. Я могу добавить курсы в список и распечатать их.Удаление узла из связанного списка указателя

Однако я не могу удалить курс из связанного списка (функция remove_course). По какой-то причине список CourseList, который я перехожу в delete_from_list, равен 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 
+0

Что такое 'BST'? –

+0

Одна проблема: 'strcpy (c-> name, & course_name);' -> 'strcpy (c-> name, & course_name);'. –

+0

@ MichaelWalz Двоичное дерево поиска, которое я еще не добавил. Но теперь он в файлах заголовков :) – BriannaXD

ответ

2

Вы никогда не инициализировать переменную master в функции main. Это означает, что оно будет иметь неопределенное значение, а его использование неинициализируется, приведет к неопределенным поведением.

Вы должны инициализировать его в NULL указатель:

CourseList master = NULL; 

Что происходит теперь, когда вы не инициализировать переменную, является то, что в вашей insert_at_front функции имеют

newNode->next = *cl; 

Поскольку *cl - master от main, и он неинициализирован, он будет иметь, казалось бы, случайное значение, одно это скорее всего не NULL, и поэтому будет казаться, что новый узел будет иметь следующий узел в списке, когда на самом деле его нет.

Это приводит к тому, что цикл в delete_from_list продолжается до фактического последнего узла в списке, и вы будете разыменовывать данные, которые не принадлежат ни одному узлу или данным, которые вы выделили.