Przykład zastosowania listy jednokierunkowej - poprawność kodu

0

Bry, czytając książkę trafiłem na następujący przykład pokazujący jak można zastosować listę jednokierunkową i mam pytanie czy ten kod jest poprawny, a dokładnie jego część dotycząca usuwania listy? GCC kompiluje i tak otrzymany program wykonuje się, a MSVSC kompiluje, ale przerywa wykonywanie we wspomnianym momencie. Pozdrawiam.

/* films2.c -- using a linked list of structures */
#include <stdio.h>
#include <stdlib.h> /* has the malloc prototype */
#include <string.h> /* has the strcpy prototype */
#define TSIZE 45 /* size of array to hold title */

struct film {
	char title[TSIZE];
	int rating;
	struct film * next; /* points to next struct in list */
};

char * s_gets(char * st, int n);

int main(void)
{
	struct film * head = NULL;
	struct film * prev, *current;
	char input[TSIZE];
	/* Gather and store information */
	puts("Enter first movie title:");
	while (s_gets(input, TSIZE) != NULL && input[0] != '\0')
	{
		current = (struct film *) malloc(sizeof(struct film));
		if (head == NULL) /* first structure */
			head = current;
		else /* subsequent structures */
			prev->next = current;
		current->next = NULL;
		strcpy(current->title, input);
		puts("Enter your rating <0-10>:");
		scanf("%d", &current->rating);
		while (getchar() != '\n')
			continue;
		puts("Enter next movie title (empty line to stop):");
		prev = current;
	}
	/* Show list of movies */
	if (head == NULL)
		printf("No data entered. ");
	else
		printf("Here is the movie list:\n");
	current = head;
	while (current != NULL)
	{
		printf("Movie: %s Rating: %d\n",
			current->title, current->rating);
		current = current->next;
	}
	/* Program done, so free allocated memory */
	current = head;
	while (current != NULL)
	{
		free(current);
		current = current->next;
	}
	printf("Bye!\n");
	getchar();
	return 0;
}
char * s_gets(char * st, int n)
{
	char * ret_val;
	char * find;
	ret_val = fgets(st, n, stdin);
	if (ret_val)
	{
		find = strchr(st, '\n'); // look for newline
		if (find) // if the address is not NULL,
			*find = '\0'; // place a null character there
		else
		while (getchar() != '\n')
			continue; // dispose of rest of line
	}
	return ret_val;
}
1

Więcej byś z tego kodu zrozumiał, gdybyś podzielił go na funkcje, a nie pakował wszystko do funkcji main; Poza tym to forwardowanie funkcji s_gets w tak prostym kodzie jest co najmniej dziwne...

2

myślałam, że w książkach są ładniejsze przykłady. taką listę jednokierunkową w C można pokazać bardziej klarownie.

0

Dziękuję za odpowiedzi. Co do książki, to taka jest zalecana literatura... Z tego co patrzyłem, to dalej jest to napisane z podziałem na funkcje. Może tutaj autor pokazuje ten sposób, żeby poźniej czytelnik mógł zobaczyć różnicę. :)
A jak dokładnie działa ta pętla, która zwalnia pamięć?

current = head;
	while (current != NULL)
	{
		free(current);
		current = current->next;
	} 

To nie jest tak, że najpierw się coś usuwa, a później do tego odwołuje?

2

tak ten kod najpierw zwalnia pamięć pod wskaźnikiem current a potem się do niej odwołuje (a już została zwolniona).
to jest błędnie, popraw sobie bodajże na;

	current = head;
	struct film *next;
	while (current != NULL) {
		next = current->next;	
		free(current);
		current = next;
	}

przetrzymasz sobie ten adres (następnego elementu) w tym dodatkowym wskaźniku next (na typ strukturalny film).

0

Poszukałem trochę i to chyba błąd w druku (czy też jego odpowiednik dla e-book'a) jest, bo w polskiej wersji językowej, co prawda nie ma tej pętli w samym kodzie, ale za to jest jej opis parę akapitów dalej (chyba kolejny błąd) i tam jest poprawnie.
Jeszcze tylko mnie intryguje, dlaczego w Visual Studio przerywa wykonywanie programu, a na Debian'ie program skompilowany za pomocą GCC wykonuje się do samego końca jakby nic się nie działo?

1

no w Linuxie się nie wywala. nie wiem od czego to zależy, może free i malloc tak zaimplementowano, żeby tolerowały takie błędy. jakby nie było za pomocą valgrind w Linuxie możesz sobie podejrzeć, co tam się dzieje naprawdę :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1