代码如下: 出自《C Primer Plus》第六版_中文版
// This program creates a linked list of films and displays them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TSIZE 45
struct film{
char title[TSIZE];
int rating;
struct film *next;
};
char *s_gets(char *st, int n);
int main(int argc, char const *argv[])
{
struct film *head = NULL;
struct film *prev, *current;
char input[TSIZE];
printf("Enter first movie title (or enter to quit): ");
while(s_gets(input, TSIZE)!= NULL && input[0]!= '\0')
{
current = (struct film*) malloc(sizeof(struct film));
if (head == NULL)
head = current;
else
prev->next = current;
current->next = NULL;
strcpy(current->title, input);
printf("Enter your rating <0-10>: ");
scanf("%d", ¤t->rating);
while (getchar()!='\n')
continue;
printf("Enter next movie title (or enter to quit): ");
prev=current;
}
if (head == NULL)
printf("No data entered. ");
else
printf("Here is the list of films: \n");
current = head;
while (current!= NULL)
{
printf("Movie: %s, Rating: %d\n",
current->title, current->rating);
current = current->next;
}
current = head;
while (current!= NULL)
{
printf("freeing memory for %s\n", current->title);
current=head;
head=head->next;
free(current);
}
fflush(stdout);
printf("Bye!\n");
fflush(stdout);
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');
if (find) {
*find = '\0';
} else {
while (getchar()!= '\n')
continue;
}
}
return ret_val;
}
这是运行程序的输出:
PS C:\Develop\c\c> gcc .\film2.c -o .\film2
PS C:\Develop\c\c> .\film2
PS C:\Develop\c\c> gcc .\film2.c -o film2
Enter first movie title (or enter to quit): ashah
Enter your rating <0-10>: 4
Enter next movie title (or enter to quit): dhaah
Enter your rating <0-10>: 2
Enter next movie title (or enter to quit): adhazb
Enter your rating <0-10>: 1
Enter next movie title (or enter to quit):
Here is the list of films:
Movie: ashah, Rating: 4
Movie: dhaah, Rating: 2
Movie: adhazb, Rating: 1
PS C:\Develop\c\c> .\film2.exe
Enter first movie title (or enter to quit): SG
Enter your rating <0-10>: 32
Enter next movie title (or enter to quit): aghah
Enter your rating <0-10>: 4
Enter next movie title (or enter to quit):
Here is the list of films:
Movie: SG, Rating: 4
Movie: sahhd, Rating: 32
Movie: aghah, Rating: 4
PS C:\Develop\c\c> ^C
PS C:\Develop\c\c> ^C
PS C:\Develop\c\c> gcc .\film2.c -o film2
PS C:\Develop\c\c> .\film2.exe
Enter first movie title (or enter to quit): asg
Enter your rating <0-10>: 4
Enter next movie title (or enter to quit): adeha
Enter your rating <0-10>: 3
Enter next movie title (or enter to quit):
Here is the list of films:
Movie: asg, Rating: 4
Movie: adeha, Rating: 3
Movie: aash, Rating: 3
freeing memory for asg
PS C:\Develop\c\c> .\film2.exe
Enter first movie title (or enter to quit): gag
Enter your rating <0-10>: 3
Enter next movie title (or enter to quit):
Here is the list of films:
Movie: gag, Rating: 3
freeing memory for gag
freeing memory for eD
PS C:\Develop\c\c>
PS C:\Develop\c\c>
PS C:\Develop\c\c> gcc .\film2.c -o film2
Enter next movie title (or enter to quit): adehg
Enter your rating <0-10>: 32
Enter next movie title (or enter to quit):
Here is the list of films:
Movie: asg, Rating: 326
Movie: adehg, Rating: 32
freeing memory for asg
freeing memory for }5P
freeing memory for adehg
PS C:\Develop\c\c>
PS C:\Develop\c\c>
PS C:\Develop\c\c>
PS C:\Develop\c\c>
PS C:\KuGou\mp4> C:\Develop\c\c\film2.exe
Enter first movie title (or enter to quit): sgag
Enter your rating <0-10>: 3
Enter your rating <0-10>: 4
Enter next movie title (or enter to quit): jpsn
Enter next movie title (or enter to quit):
Here is the list of films:
Movie: sgag, Rating: 3
Movie: ahjkjoa, Rating: 4
Movie: jpsn, Rating: 56
freeing memory for sgag
freeing memory for 锢z
freeing memory for ahjkjoa
freeing memory for jpsn
PS C:\KuGou\mp4> C:\Develop\c\c\film2.exe
Enter first movie title (or enter to quit): dfsj
Enter your rating <0-10>: 3
Enter next movie title (or enter to quit): jopiap
Enter your rating <0-10>: 4
Enter next movie title (or enter to quit): irwal
Enter your rating <0-10>: 6
Enter next movie title (or enter to quit):
Here is the list of films:
Movie: dfsj, Rating: 3
Movie: jopiap, Rating: 4
Movie: irwal, Rating: 6
freeing memory for dfsj
freeing memory for 谟I
freeing memory for jopiap
freeing memory for irwal
并且程序在打印最后一句“freeing memory for irwal”后要等待几十秒才能退出
起初我以为 free() 运行时代码被破坏,或者缓冲区没有刷新,所以我添加了这两行:
printf("freeing memory for %s\n", current->title);
fflush(stdout);
但新的问题又出现了:
为什么为一个不存在的结构释放了内存,而程序仍然正常释放内存?
为什么??????
问题出在这个循环中:
while (current!= NULL)
{
printf("freeing memory for %s\n", current->title);
current=head;
head=head->next;
free(current);
}
调用
free(current)
后,current
所指向的内存不再有效。因此,当您使用 current->title
时,下一次迭代您将访问该无效内存并具有 未定义的行为。
您需要更改做事的顺序:
while (current!= NULL)
{
printf("freeing memory for %s\n", current->title);
head=head->next; // Get the next node in the list
free(current); // Free the current node
current=head; // Make the next node the current node
}