【问题标题】:wrong output when code runs problem with linked list?代码运行时输出错误,链表有问题?
【发布时间】:2019-05-11 20:06:05
【问题描述】:

运行下面的代码后,我得到了输出

名称:(空)|平均绩点:0.000000 |年份:(NULL)

链接列表没有正确实现吗?我目前正在使用一个 makefile 并引入一个 test.data 文件,其中包含名称、gpa 和 Senior/ect ..

奥利 2.9 级新生
约翰 3.2 高级
朱莉 2.2 新生
乔1.8级新生
玛丽 3.8 高级
苏 3.4 初级
简 2.7 高级
鲍勃 2.8 高级
弗雷德 3.2 新生
比尔 3.3 初级

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "students.h"

Student *top = NULL;
Student *temp, *temp1, *temp2;

// Creates the entire linked list from the file.                                                                                                                           
// Should call readNext and push                                                                                                                                           
// Returns head of the linked list                                                                                                                                         
Student *buildStudentList()
{
  Student *p;
  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));

  scanf("%s", s -> name);
  scanf("%f", &s -> gpa);
  scanf("%s", s -> year);
  s->next = 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));

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;

top = student;

}
//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;
for(i = 1; i < position -1; i++)
    {
   temp = temp -> next;
}
if(temp == NULL)
    {
       //blank                                                                                                                                                             
    }
else
    {
   s -> next = temp -> next;
   temp -> next = s;
}
}
//Displays contents of a single student structure                                                                                                                          
void display(Student *s){

printf("NAME:%s  | GPA: %f       | YEAR:%s
", 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;
temp2 = temp1 -> next;

while(temp1 != NULL)
{
   free(temp1);
   temp1 = temp2;
 }

 if(temp2 != NULL)
   {
      temp2 = temp2 -> next;
   }

}
//Main function tests your functions.                                                                                                                                      
int main()
{
printf("Program Started
");

//Construct Linked List from Standard Input                                                                                                                                
Student *list = buildStudentList();

//Insert a new student in desired position                                                                                                                                 
Student *s = makeStudent("Max",3.0, "senior");
insert(list, s, 3);

//Display entire linked list                                                                                                                                               
displayAll(list);

//Free all heap memory                                                                                                                                                     
cleanUp(list);

    printf("Program Successful Exit
");
    exit(EXIT_SUCCESS);
}

【问题讨论】:

  • 请正确格式化此代码。很难读。
  • 您能说服我们您的 scanfs 有效吗?您的代码似乎非常信任,而不是检查返回值。
  • 你做了一些调试吗?要么使用调试器,要么使用多个偏执检查并输出相关数据。尝试找出哪个功能失败。创作、阅读、输出……
  • Student 的字段nameyearchar 数组或指针。 (你没有显示它。)如果它们是数组,makeStudent 中的赋值会导致编译器错误。但是,如果它们是指针,则在调用 scanf 之前永远不会为它们分配 readNext。这会导致未定义的行为。
  • 它们不是使用 malloc(sizeof(Student) 行分配的吗?

标签: c pointers struct malloc


【解决方案1】:

由于您没有发布您的struct 定义,我不得不猜测(例如)namechar *name; 还是(例如char name[100];)。在代码中,它使用它作为指针。

所以...

您的 readNextmakeStudent 没有为字符串(char * 指针)nameyear 分配空间,因此它们可能存在段错误。

insert 在真正需要Student **list 时采用Student *list

IMO,您应该有一个单独的 List 类型以避免混淆(只有一个元素:Student *head;)。所以,无论你有Student *list,你都用List *list替换它

当你这样做时,当你的意思是一个列表时,你不必传递Student ** [双星] 指针。使用list-&gt;head*list 更容易且更具描述性。

另外,保持一致。如果某些函数修改列表[他们拥有到],则使用Student **list。其他人使用Student *list,但它们也应该保持一致。

不需要各种 global 范围的临时变量。这些应该是函数作用域并使用更具描述性的名称。

您的insert 有问题。如果找到 no 位置匹配,它将 orphan 尝试插入的节点(例如,在您的示例中的位置 99 处插入)。通常是在尾部插入或返回错误代码。此外,由于您拥有的代码,position 对我意味着什么并不完全清楚。它可能是“插入之前”或“插入之后”第 N 个节点。

不能在双引号字符串中插入文字换行符。因此,请使用\n 转义序列(例如)printf("hello world\n");

此外,采用 no 参数的函数应使用void(例如)而不是int main(),使用int main(void)

这是您的代码的清理版本,包含我上面提到的内容:

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

//#include "students.h"
typedef struct student Student;
struct student {
    Student *next;
    float gpa;
    char *name;
    char *year;
};

typedef struct list {
    Student *head;
} List;

//insert a new student node at the head of the linked list
void
push(List *list, Student *student)
{

    student->next = list->head;
    list->head = student;
}

//Return a student structure stored on the heap
Student *
makeStudent(char *name, float gpa, char *year)
{

    Student *s = (Student *) malloc(sizeof(Student));
    s->name = strdup(name);
    s->gpa = gpa;
    s->year = strdup(year);
    s->next = NULL;

    return s;
}

//Read a single line from standard input and return a student structure located on the heap
Student *
readNext(void)
{
    char name[1000];
    float gpa;
    char year[1000];
    Student *s = NULL;

    int count = scanf("%s %f %s",name,&gpa,year);

    if (count == 3) {
        printf("readNext: name='%s' gpa=%g year='%s'\n",name,gpa,year);
        s = makeStudent(name,gpa,year);
    }

    return s;
}

// Creates the entire linked list from the file.
// Should call readNext and push
// Returns head of the linked list
List *
buildStudentList(List *list)
{
    Student *p;

    while (1) {
        p = readNext();
        if (p == NULL)
            break;
        push(list, p);
    }

    return list;
}

//Insert a student node in the desired position on the linked list
int
insert(List *list, Student *s, int position)
{
    Student *cur;
    Student *prev;
    int i;
    int goflg;

    //position -= 1;

#if 0
    i = 1;  // insert before Nth position
#else
    i = 0;  // insert after Nth position
#endif
    prev = NULL;

    for (cur = list->head;  (cur != NULL) && (i < position);
        ++i, cur = cur->next) {
        prev = cur;
    }

    // this may not be needed -- usual is to insert at tail if position is not
    // found -- this will orphan the node to be inserted
#if 0
    goflg = (i == position);
#else
    goflg = 1;
#endif

    if (goflg) {
        s->next = cur;
        if (prev != NULL)
            prev->next = s;
        else
            list->head = s;
    }

    return goflg;
}

//Displays contents of a single student structure
void
display(Student *s)
{

    printf("NAME:%s  | GPA: %f       | YEAR:%s\n", s->name, s->gpa, s->year);

}

//Displays contents of the entire linked list
void
displayAll(List *list)
{
    Student *temp = list->head;

    while (temp != NULL) {
        display(temp);
        temp = temp->next;
    }

}

//Delete all data allocated on the heap before terminating program
void
cleanUp(List *list)
{
    Student *cur;
    Student *next;

    for (cur = list->head;  cur != NULL;  cur = next) {
        next = cur->next;
        free(cur->name);
        free(cur->year);
        free(cur);
    }

    list->head = NULL;
}

//Main function tests your functions.
int
main(void)
{
    List top = { NULL };
    List *list;

    printf("Program Started\n");

    //Construct Linked List from Standard Input
    list = buildStudentList(&top);

    //Insert a new student in desired position
    Student *s = makeStudent("Max", 3.0, "senior");
    insert(list, s, 3);

    //Display entire linked list
    displayAll(list);

    //Free all heap memory
    cleanUp(list);

    printf("Program Successful Exit\n");
    exit(EXIT_SUCCESS);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-30
    • 2022-11-04
    • 2017-05-16
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 2020-12-31
    相关资源
    最近更新 更多