2015-10-03 2 views
-1

У меня возникли проблемы с созданием единого списка. Этот связанный список должен получать имя, GPA, ключ --- генерировать узлы --- print --- де-выделить память. Однако, похоже, в моем коде есть ошибки. Но я не могу найти, где они. Не могли бы вы рассказать мне, где неправильный код, если вы его найдете?Исключение при создании односвязного списка

Необработанная ошибка исключения 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

Ваших поручений curptr, preptr и т.д. в методе newnode отбрасывается, как только этот метод возвращает. Попробуйте добавить '&' к параметрам, сделав их ссылками. И вам приятных выходных! – Kenney

+2

Название этого вопроса не является конкретным. Любой человек с такой же проблемой в будущем не сможет его найти. –

+1

Как сказал Кенни, ваши указательные головы, хвост, ...передаются значениями, вы изменяете их значения внутри функции newnode, но изменение остается локальным. Если у вас есть только компилятор C, вы должны пройти ** head ** tail, ... и написать * head = newnode, * tail = newnode, .... – OAnt

ответ

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 snce, он возвращает void *, который присваивается любому указателю.

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

То же самое здесь. Не нужно бросать NULL.

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

Как только вы обнаружили, что проблема с распределением памяти, вам лучше вернуться из этой функции после печати сообщения об ошибке. В противном случае ваш код будет продолжать работать внутри этой функции, получая доступ к полям структуры, которые не были выделены.

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, а затем reassigng его curptr = temp;

+0

@ Побалуйте вас. –

 Смежные вопросы

  • Нет связанных вопросов^_^