当我尝试运行这段代码时,我得到的只是一个警告,gets()太危险了。然后当我运行它时,我得到空白。我应该显示这个:
Ollie 2.9 freshmen
John 3.2 senior
Julie 2.2 freshmen
Joe 1.8 freshmen
Mary 3.8 senior
Sue 3.4 junior
Jane 2.7 senior
Bob 2.8 senior
Fred 3.2 freshmen
Bill 3.3 junior
这是我的代码:
Student *top = NULL; // to point top node of list
Student * temp, *temp1, *temp2; // for traversing list
// Creates the entire linked list from the file.
// Should call readNext and push
// Returns head of the linked list
Student *buildStudentList()
{
Student *p; // will hold the data to be pushed in list
p = readNext();
push(&top, p);
return top; //TODO: Change return
}
//Read a single line from standard input and return a student structure located on the heap
Student *readNext()
{
Student *s = (Student*)malloc(sizeof(Student)); // allocating dynamic memory in heap
printf("Please Enter Student Name, gpa, year :");
gets(s->name);
scanf("%f", &s->gpa);
gets(s->year);
s->next = NULL; // initially make next as NULL
return s; //TODO: Change return
}
//Return a student structure stored on the heap
Student *makeStudent(char *name, float gpa, char *year)
{
Student *s = (Student*)malloc(sizeof(Student));// allocating memory in heap
s->name = name;
s->gpa = gpa;
s->year = year;
s->next = NULL;
return s; //TODO: Change return
}
//insert a new student node at the head of the linked list
void push(Student **list, Student *student)
{
top = *list;
student->next = top; // assign current top node of list to be second node of the list
top = student; // make current node as top node of the list
printf("push successful.n");
}
//Insert a student node in the desired position on the linked list
void insert(Student *list, Student *s, int position)
{
int i;
top = list;
temp = top;// temp is for traversing the list
for (i = 1; i < position - 1; i++) // loop to reach desired position in the list
{
temp = temp->next;
}
if (temp == NULL)
{
printf("Position does not exist.n");
}
else
{
s->next = temp->next;
temp->next = s;
}
}
//Displays contents of a single student structure
void display(Student *s) {
printf("NAME:%st| GPA:%ft| YEAR:%sn", s->name, s->gpa, s->year);
}
//Displays contents of the entire linked list
void displayAll(Student *list)
{
temp = list;
while (temp != NULL)
{
display(temp);
temp = temp->next;
}
}
//Delete all data allocated on the heap before terminating program
void cleanUp(Student *list)
{
temp1 = list; // will point to the top node of list
temp2 = temp1->next; // will point to the second node of the list
while (temp1 != NULL)
{
free(temp1);
temp1 = temp2;
temp2 = temp2->next;
}
printf("Cleanup Successful.n");
}
//Main function tests your functions.
int main()
{
Student *list, *s;
printf("Program Started ");
//Construct Linked List from Standard Input
list = buildStudentList();
//Insert a new student in desired position
s = makeStudent("Max", 3.0, "senior");
insert(list, s, 1);
//Display entire linked list
displayAll(list);
//Free all heap memory
cleanUp(list);
printf("Program Successful Exit ");
return 0;
//exit(EXIT_SUCCESS);
}
这是我得到的输出:
Program Started
Segmentation fault
我应该尝试使用 fgets() 而不是 gets()吗?我尝试执行的输出是不同文件的一部分,这会影响它吗?
忽略警告从来都不是正确的做法。目的不仅仅是使用一些黑客删除警告,而是解决产生警告的根本原因。在这种特殊情况下,编译器明确警告您使用gets
太危险了。你为什么不听从这么明确的警告?
从C11开始,gets
已从标准中删除。
gets()
函数不执行边界检查,因此此函数极易受到缓冲区溢出攻击。它不能安全使用(除非程序在限制stdin
上可以显示的内容的环境中运行)。因此,该函数已在 C99 标准的第三个更正中弃用,并在 C11 标准中完全删除。fgets()
和gets_s()
是推荐的替代品。切勿使用
gets()
。
另请查看结构成员的内存分配/释放。
另请阅读此问题,了解是否应强制转换 malloc 的结果。
您好,我浏览了您的代码,假设您的结构描述如下:
typedef struct Student_s{
char name[32];
float gpa;
char year[5];
struct Student_s* next;
}Student;
P.W.在之前的回答中已经指出了gets()
的问题 .您可以使用scanf("%s",s->name)
而不是gets()
,
在makeStudent()
中,您应该使用strcpy()
来复制字符串。[ 原因 ]
同样cleanUp()
考虑释放最后一个节点的情况,temp1
将指向最后一个节点,temp2
指向NULL
。在这种情况下,如果您执行temp2 = temp2->next
将导致分段错误。您可以通过将语句括在if
中来避免这种情况。
if(temp2 != NULL){
temp2 = temp2->next;
}