当我尝试运行此代码时,我得到的只是一个警告,即get()太危险了,不能使用。然后,当我运行它时,我变得空白。我想显示这个:
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:%s\t| GPA:%f\t| YEAR:%s\n", 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()吗?我尝试执行的输出是另一个文件的一部分,对它有影响吗?
答案 0 :(得分:3)
忽略警告绝不是正确的事情。目的不仅是使用一些技巧来消除警告,而且还可以解决产生警告的根本原因。在这种情况下,编译器明确警告您使用gets
太危险了。您为什么不听这样清晰的警告?
gets
已从标准中删除。
gets()
函数不执行边界检查,因此此函数极易受到缓冲区溢出攻击。它不能安全使用(除非程序在限制stdin
上显示内容的环境中运行)。因此,该功能在第三更正版中已不支持C99标准,而在C11标准中已完全删除。建议使用fgets()
和gets_s()
。请勿使用
gets()
。
还要查看您对结构成员的内存分配/取消分配。
答案 1 :(得分:0)
您好,假设您的结构描述如下,请仔细阅读您的代码:
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()
复制字符串。 [Reason]
还要在cleanUp()
中考虑释放最后一个节点的情况,temp1
指向最后一个节点,而temp2
指向NULL
。在这种情况下,如果您执行temp2 = temp2->next
,则会得到segmentation fault。您可以通过将语句放在if
中来避免这种情况。
if(temp2 != NULL){
temp2 = temp2->next;
}