Deleting in linked lists? - c

I wrote the following code:
#include<stdio.h>
struct student{
char name[25];
double gpa;
struct student *next;
};
struct student *list_head;
struct student *create_new_student(char nm[], double gpa)
{
struct student *st;
printf("\tcreating node\t");
printf("\nName=%s \t Gpa= %.2f\n", nm, gpa);
st = (struct student*)malloc(sizeof (struct student ));
strcpy(st->name, nm);
st->gpa = gpa;
st->next = NULL;
return st;
}
void printstudent(struct student *st)
{
printf("\nName %s,GPA %f\n", st->name, st->gpa);
}
void insert_first_list(struct student *new_node)
{
printf("\nInserting node: ");
printstudent(new_node);
new_node->next = list_head;
list_head = new_node;
}
struct student *delete_first_node()
{
struct student *deleted_node;
printf("\nDeleting node: ");
printstudent(deleted_node);
list_head = list_head->next;
return deleted_node;
}
void printlist(struct student *st)
{
printf("\nPrinting list: ");
while(st != NULL) {
printstudent(st);
st = st->next;
}
}
int main()
{
struct student *other;
list_head = create_new_student("Adil", 3.1);
other = create_new_student("Fatima", 3.8);
insert_first_list(other);
printlist(list_head);
other = delete_first_node();
printlist(list_head);
return 0;
}
When I run it, there are no errors or warnings. However, it stops at the delete part.The message says the program has stopped working.
Can you please help me find the problem?

In function delete_first_node the node deleted_node is not initialized and passed to function printstudent which try to access its member, results in undefined behavior.
The function should be
struct student *delete_first_node(){
struct student *deleted_node = list_head;
printf("\nDeleting node: ");
if(deleted_node != NULL)
{
printstudent(deleted_node);
list_head= list_head->next;
free(deleted_node);
}
else
printf("List is emty\n");
return list_head;
}

Related

Segmentation fault error in Linked-List program

I'm facing the segmentation fault error in the following dynamic linked list implementation; GDB shows the issue is on the node = node->next line in the "l_print" function of the linked-list ("LIST_CL.H" file). Anyone can help? I even tried "drawing debug" on paper but still I'm not getting the issue here.
Note: I report the whole code for both the insert and the print, in case it's useful. Therefore LIST.C file include the "switch case 6" to insert the element ("l_add" function in "LIST_CL.H" file) and the "switch case 1" to print the list ("l_print" function in "LIST_CL.H" file)
Note: The issue only happen when the list has one or more items. There's no errors when the list is empty ("list_cl" struct has NULL for both head and tail nodes)
LIST.C:
#include <stdio.h>
#include <string.h> //for strcpy
#include "cl_list.h"
#include "list_cl.h"
#define STRING_SIZE 25
int main(){
list_cl class = L_EMPTYLIST_CL;
puts("Select command:");
puts("0. Exit.");
puts("1. Insert node.");
puts("6. Print all nodes in the linked list.");
int k = 0;
scanf("%d", &k);
while(k != 0){
switch(k){
case 1:
char cf[17] = "";
char first_name[STRING_SIZE] = "";
char last_name[STRING_SIZE] = "";
getchar();
puts("Insert name:");
fgets(first_name, sizeof(first_name), stdin);
puts("Insert surname:");
fgets(last_name, sizeof(last_name), stdin);
puts("Insert fiscal code:");
fgets(cf, sizeof(cf), stdin);
client cliente;
strcpy(cliente.cf, cf);
cliente.first_name = first_name;
cliente.last_name = last_name;
class = l_add_cl(class, cliente);
puts("Node inserted.");
break;
case 6:
l_print(class);
break;
default:
break;
}
scanf("%d", &k);
}
}
LIST_CL.H:
list_cl l_add_cl(list_cl l, client p){
l_node node;
node.id = 1;
node.person = p;
node.next = NULL;
if(l.head == NULL){
//List is empty
l.head = &node;
l.tail = &node;
} else {
l.tail -> next = &node;
l.tail = &node;
}
return l;
}
void l_print(list_cl l){
l_node *node = NULL;
node = l.head;
while(node != NULL){
//client *cliente = &node->person;
//printf("ID Elemento: %d | Name: %s Surname: %s Fiscal Code: %s", node->id, cliente->first_name, cliente->last_name, cliente->cf);
node = node->next; // SEGMENTATION FAULT ERROR HERE!
}
}
CL_LIST.H:
#include "client.h"
typedef struct _node {
unsigned int id;
client person;
struct _node *next;
} l_node;
typedef struct {
l_node *head;
l_node *tail;
} list_cl;
#define L_EMPTYLIST_CL {NULL,NULL}
CLIENT.H:
typedef struct {
char cf[17];
char *first_name;
char *last_name;
} client;
Fixed code:
LIST.C:
#include <stdio.h>
#include <string.h> //for strcpy
#include "cl_list.h"
#include "list_cl.h"
#define STRING_SIZE 25
int main(){
list_cl class = L_EMPTYLIST_CL;
puts("Seleziona un comando:");
puts("0. Exit.");
puts("1. Insert one node.");
puts("6. Print all nodes.");
int k = 0;
scanf("%d", &k);
while(k != 0){
switch(k){
case 1:
char cf[17] = "";
//char first_name[STRING_SIZE] = ""; THIS CAUSE DATA INCONSISTENCY
//char last_name[STRING_SIZE] = ""; THIS CAUSE DATA INCONSISTENCY
char *first_name = malloc(sizeof(char)*STRING_SIZE);
char *last_name = malloc(sizeof(char)*STRING_SIZE);
getchar();
puts("Insert name:");
//fgets(first_name, sizeof(first_name), stdin); ISSUE WITH SIZE OF FIRST_NAME
fgets(first_name, sizeof(char)*STRING_SIZE, stdin);
puts("Insert surname:");
//fgets(last_name, sizeof(last_name), stdin); ISSUE WITH SIZE OF LAST_NAME
fgets(last_name, sizeof(char)*STRING_SIZE, stdin);
puts("IInsert fiscal code:");
fgets(cf, sizeof(cf), stdin);
client *cliente = malloc(sizeof(client));
strcpy(cliente->cf, cf);
cliente->first_name = first_name;
cliente->last_name = last_name;
class = l_add_cl(class, *cliente);
puts("Element inserted.");
break;
case 6:
l_print(class);
break;
default:
break;
}
puts("Select command:");
scanf("%d", &k);
}
}
LIST_CL.H
list_cl l_add_cl(list_cl l, client p){
l_node *node = malloc(sizeof(struct _node));
node->id = 1;
node->person = p;
node->next = NULL;
if(l.head == NULL){
//Empty list
l.head = node;
l.tail = node;
} else {
l.tail -> next = node;
l.tail = node;
l.tail -> next = NULL;
}
return l;
}
void l_print(list_cl l){
l_node *node = NULL;
node = l.head;
while(node != NULL){
client *cliente = &node->person;
printf("ID Element: %d | Name: %s Surname: %s Fiscal code: %s", node->id, cliente->first_name, cliente->last_name, cliente->cf);
node = node->next;
}
}
CL_LIST.H
#include "client.h"
typedef struct _node {
unsigned int id;
client person;
struct _node *next;
} l_node;
typedef struct {
l_node *head;
l_node *tail;
} list_cl;
#define L_EMPTYLIST_CL {NULL,NULL}
CLIENT.H
typedef struct {
char cf[17];
char *first_name;
char *last_name;
} client;

Why is there an infinite loop here? (linked list printing)

I am doing a little practice with linked lists, these are the structures.
typedef struct roomList roomList;
typedef struct school school;
typedef struct studentList studentList;
roomList *getRoom(school* school, int class, int roomNr);
struct studentList{
char *name;
int class;
float grade;
int roomNr;
studentList *next;
studentList *prev;
};
struct roomList{
int nrOfStudents;
int roomNr;
studentList *students; //pointer to student list.
roomList *next;
roomList *prev;
};
struct school{
int totalStudents;
roomList *Class[13]; //array of classes, each index contains rooms.
};
This is where the infinite loop is happening, it's a function to print all students within a room.
void printRoom(school *school, int class, int roomNr)
{
roomList *room = getRoom(school, class, roomNr);
studentList *student;
if(room != NULL)
{
int i = 1;
printf("Nr of students: %d\n", room->nrOfStudents);
while(room->nrOfStudents != 0 && student != NULL)
{
student = room->students;
printf("%d - \"%s\" ",i, student->name);
student = student->next;
i++;
}
}
}
This is how I'm creating a student
studentList *createStudent(int class, char *name, int roomNr)
{
studentList *newNode;
newNode = (studentList*)calloc(1, sizeof(studentList));
newNode->class = class;
newNode->name = (char*)malloc(strlen(name)+1);
strcpy(newNode->name, name);
newNode->roomNr = roomNr;
newNode->grade = 0;
newNode->next = newNode->prev = NULL;
return newNode;
}
And finally, this is how I'm inserting a student into a room.
void insertStudentToRoom(school* school, int class, int roomNr, char *name)
{
roomList *room;
room = getRoom(school, class, roomNr);
studentList *newStudent;
newStudent = createStudent(class, name, roomNr);
if(room->students != NULL)
{
newStudent->next = room->students;
room->students->prev = newStudent;
room->students = newStudent;
room->nrOfStudents++;
school->totalStudents++;
}
else
{
room->students = newStudent;
room->nrOfStudents++;
school->totalStudents++;
}
}
The infinite infinite loop only happens when I insert more than one student into a room, and exits fine when there's only one student, I've tried fumbling around with exit conditions for my while() to no avail.
while(room->nrOfStudents != 0 && student != NULL)
{
student = room->students;
printf("%d - \"%s\" ",i, student->name);
student = student->next;
i++;
}
Look closely. You never change room in the loop. So student = room->students; is going to set the very same value for student every single time in the loop. If it didn't break after the first time, it won't break any other time.
You probably want to take student = room->students; out of the loop. You only want to point at the first student in the room once.

Pointers and binary search tree

I am working on a program that uses a binary search tree (as an exercise).
My problem is that when I try to add a customer(in the middle of my code lines 65-69) I get an error that BS_node is undeclared, though I insert struct BST_node *root in this function..
Part of my code is below, just for the readers to read it easier, if requested I can upload the full code ! Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING 50
void flush();
struct customer {
char *name;
char *address;
char *email;
};
struct double_linked_list {
struct customer *data;
struct double_linked_list *previous;
struct double_linked_list *next;
};
struct double_linked_list *customers_head=0;
struct BST_node {
struct double_linked_list *data;
struct BST_node *left;
struct BST_node *right;
};
struct BST_node *BST_email_root = 0;
struct BST_node *BST_find_customer(struct BST_node *root, char *email) {
if (root==NULL)
return NULL;
if (strcmp(email,root->data->data->email)==0)
return root;
else
{
if (strcmp(email,root->data->data->email)==-1)
return BST_find_customer(root->left,email);
else
return BST_find_customer(root->right,email);
}
}
void find_customer() {
char email[MAX_STRING];
struct double_linked_list *l;
struct BST_node *b;
printf("Give the email of the customer (up to %d characters) : ", MAX_STRING-1);
gets(email);
b = BST_find_customer(BST_email_root, email);
if (b==0)
printf("There is no customer with this email.\n");
else
{
l = b->data;
printf("Customer found! \n");
printf("Name : %s\n", l->data->name);
printf("Address : %s\n", l->data->address);
printf("Email : %s\n", l->data->email);
}
}
struct BST_node *new_BST_node(struct BST_node *root, struct double_linked_list *l)
{
if (root==NULL);
{
root = (BST_node *) malloc (sizeof(BST_node ));
if (root==NULL)
{
printf("Out of Memory!");
exit(1);
}
root->data=l;
root->left=NULL;
root->right=NULL;
}
if (strcmp(l->data->email,root->data->data->email)==-1)
root->left =new_BST_node(root->left,l);
else root->right =new_BST_node(root->right,l);
return root;
};
struct double_linked_list *new_customer()
{
char name[MAX_STRING], address[MAX_STRING], email[MAX_STRING];
struct BST_node *b;
struct double_linked_list *l;
struct customer *c;
printf("\nADDING NEW CUSTOMER\n=\n\n");
printf("Give name (up to %d characters): ", MAX_STRING-1);
gets(name);
printf("Give address (up to %d characters): ", MAX_STRING - 1);
gets(address);
printf("Give email (up to %d characters): ", MAX_STRING - 1);
gets(email);
b = BST_find_customer(BST_email_root, email);
if (b)
{
printf("Duplicate email. Customer aborted.\n");
return 0;
}
c = (struct customer *) malloc(sizeof(struct customer));
if (c == 0)
{
printf("Not enough memory.\n");
return 0;
}
c->name = strdup(name); // check for memory allocation problem
if (c->name == 0) return 0;
c->address = strdup(address); // check for memory allocation problem
if (c->address == 0) return 0;
c->email = strdup(email); // check for memory allocation problem
if (c->email == 0) return 0;
l = (struct double_linked_list*) malloc(sizeof(struct double_linked_list));
if (l == 0)
{
printf("Not enough memory.\n");
free(c->name);
free(c->address);
free(c->email);
free(c);
return 0;
}
l->data = c;
l->previous = 0;
l->next = customers_head;
if (customers_head)
customers_head->previous = l;
customers_head = l;
BST_email_root = new_BST_node(BST_email_root, l);
return l;
}
void displaymenu() {
printf("\n\n");
printf("1. New customer\n");
printf("2. Find customer using email\n");
printf("0. Exit\n\n");
printf("Give a choice (0-6) : ");
}
void flush()
{
char ch;
while ((ch = getchar()) != '\n' && ch != EOF);
}
int main() {
int choice;
do {
displaymenu();
scanf("%d", &choice);
flush();
switch (choice) {
case 1:
new_customer();
break;
case 2:
find_customer();
break;
} while (choice != 0);
return 0;
}
On the line 69, you have to specify struct BST_node instead of BST_node:
root = (struct BST_node *) malloc (sizeof(struct BST_node ));
As for the rest of the code: read the manual for gets, it's clearly a function one should not use, I'd advise replacing it with fgets. There's also a little closing bracket missing in your final switch (line 178).

display function for nested singly linked list c

Im writing database program for my c class for few days now im trying to figure out how to work with singly linked lists its pretty hard to understand I would say ,well at least for me. Overall I got part of code necessary for my project, basicaly I got functions to add client and items to client thanks to help of somebody from stackoverflow I kinda figured how to add multiple items to 1 client but now I'm in trouble figuring out how exactly can I print it ,tried to do it the way you can see im my display function but it doesnt work for items linked to client what should I change to make it work?
#include <stdio.h>
#include <stdlib.h>
struct item{
char item_name[30];
struct item *NextItem;
};
struct client{
struct client *NextClient;
char name[30];
char last_name[30];
struct item *firstItem;
struct item *lastItem;
};
struct client *head = NULL;
/////////////////////////////
struct client* FindTailClient(struct client* head)
{
struct client *temp = head;
while( temp->NextClient != NULL)
{
temp = temp->NextClient;
}
return temp;
}
/////////////////////////////
////////
struct client *GetClientData()
{
char data[30];
struct client *temp;
temp = (struct client*)malloc(sizeof(struct client));
printf("Enter the person's name--->");
scanf("%s",data);
strcpy(temp->name,data);
printf("Enter the person's last name--->");
scanf("%s",data);
strcpy(temp->last_name,data);
temp->NextClient = NULL;
return temp;
}
///////////
struct item *GetItemData()
{
struct item *temp;
char data[30];
temp = (struct item*)malloc(sizeof(struct item));
printf("Enter the item name--->");
scanf("%s",data);
strcpy(temp->item_name,data);
temp->NextItem = NULL;
return temp;
}
///////////
//////////////
struct client* AddClient()
{
struct client *temp,temp1;
temp=head;
struct client *data = GetClientData();
if(head == NULL)
{
head=data;
head->NextClient = NULL;
}
else
{
while(temp->NextClient != NULL)
{
temp=temp->NextClient;
}
data->NextClient=NULL;
temp->NextClient=data;
}
}
///////////////////
///////////////////
///////////////////
void display()
{
struct client *CurrentClient = head;
struct item *ItemCurrent = head->firstItem;
while(CurrentClient != NULL)
{
printf(" -> %s ->%s \n",CurrentClient->name,CurrentClient->last_name);
while(ItemCurrent != NULL)
{
printf(" -> %s\n",ItemCurrent->item_name);
ItemCurrent=ItemCurrent->NextItem;
}
CurrentClient=CurrentClient->NextClient;
}
}
///////////////////
void AddItemToClient(struct client* head, struct item *item)
{
item->NextItem = NULL;
if(head->firstItem == NULL) {
head->firstItem = item;
} else {
head->lastItem->NextItem = item;
}
head->lastItem = item;
}
///////////////////
struct client *find(struct client *head, char name[])
{
while (head->NextClient != NULL )
{
if (strcmp(head->name,name) == 0)
{
printf("Target found: %s\n",head->name);
return head;
}
head = head->NextClient;
}
printf("target not found");
return NULL;
}
//////////////////
int main()
{
int i;
char data[30];
char name[30];
struct client *temp;
struct client *head;
struct item *data1;
for(i=0;i<2;i++)
{
AddClient();
}
printf("Insert name to find:");
scanf("%s",name);
temp = find(&head,name);
data1 = GetItemData();
AddItemToClient(temp,&data1);
display();
}
In this line: "while(ItemCurrent != ItemLast)" - ItemLast is undeclared. Maybe you wanted to write head->lastItem, or better ItemCurrent->next != NULL.
Also, make sure you store the clients you just created to be able to access them: head = AddClient(); instead of simply AddClient();

I m trying to sort the node by score. I do not know what error i am having

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
void display(struct student *first)
{
while (first != NULL)
{
printf("\nFirst name: %s", first->firstname);
printf("\tLast name: %s", first->lastname);
printf("\tGrade: %.2f", first->grade);
printf("\t ZipCode: %s", first->zipcode);
first = first->next;
}
}
/*void add_Record(struct student *first)
{
char r[20];
struct student *t;
t = first;
while (t != NULL)
{
if (t == NULL)
{
first = (struct student*)malloc(sizeof(struct student));
printf("\nEnter the first name of the student:");
scanf("%s", first->firstname);
printf("\nEnter the last name of the student:");
scanf("%s", first->lastname);
printf("\nEnter the score of the student:");
scanf("%lf", &first->grade);
printf("\nEnter the zipcode of the student:");
scanf("%s", first->zipcode);
}
}
}
void del()
{
struct student *back, *t, *k;
char r[10];
int flag = 0;
printf("\nEnter the last name of student you want to delete:");
scanf("%s", r);
if (strcmpi(r, first->lastname) == 0)
{
first = first->next;
flag = 1;
}
else
{
back = first;
k = first->next;
while (k != NULL)
{
if (strcmpi(r, k->lastname) == 0)
{
back->next = k->next;
flag = 1;
break;
}
}
}
if (flag == 0)
printf("\nThe element not found!!!");
}
*/
void search(struct student *first)
{
char r[10];
int flag = 0;
printf("\nEnter the zipcode you want to search:");
scanf("%s", r);
struct student *t;
t = first;
while (t != NULL)
{
if (strcmp(r, t->zipcode) == 0)
{
printf("\nFirst name: %s", t->firstname);
printf("\tLast name: %s", t->lastname);
printf("\tGrade: %.2f", t->grade);
printf("\t ZipCode: %s", t->zipcode);
flag = 1;
break;
}t = t->next;
}
if (flag == 0)
printf("\nThe zipcode not in database!!");
}
void sort(struct student *first)
{
struct student *temp;
temp = NULL;
while (first != NULL)
{
if (first-> grade > first->next->grade)
{
strcpy(temp->firstname, first->firstname);
strcpy(temp->lastname, first->lastname);
temp->grade = first->grade;
strcpy(temp->zipcode, first->zipcode);
strcpy(first->firstname, first->next->firstname);
strcpy(first->lastname, first->next->lastname);
first->grade = first->next->grade;
strcpy(first->zipcode, first->next->zipcode);
strcpy(first->next->firstname, temp->firstname);
strcpy(first->next->lastname, temp->lastname);
first->next->grade = temp->grade;
strcpy(first->next->zipcode, temp->zipcode);
break;
}
}
printf("\nThe sorted record by score are: \n");
display(first);
}
int main(void)
{
struct student *first = NULL, *last = NULL;
struct student *temp;
int n;
printf("\nEnter the number of student:");
scanf("%d", &n);
int i;
for (i = 0; i < n; i++)
{
temp = (struct student*)malloc(sizeof(struct student));
printf("\nEnter the first name of the student:");
scanf("%s", temp->firstname);
printf("\nEnter the last name of the student:");
scanf("%s", temp->lastname);
printf("\nEnter the grade of the student:");
scanf("%lf", &temp->grade);
printf("\nEnter the zipcode of the student:");
scanf("%s", temp->zipcode);
temp->next = first;
first = temp;
}
int o;
o = 1;
while (o != 0)
{
printf("\nMENU\n");
printf("\nEnter 1 for displaying database.");
printf("\nEnter 2 for inserting an record.");
printf("\nEnter 3 for deleting a record by lastname.");
printf("\nEnter 4 for searching a record by zipcode.");
printf("\nEnter 5 for sorting record by score.");
printf("\nEnter 0 for exit!");
printf("\nEnter the choice:");
scanf("%d", &o);
switch (o)
{
case 1:display(first); break;
/*case 2:insertafter(*first); break;
case 3:del(); break;*/
case 4:search(first); break;
case 5: sort(first); break;
case 0:exit(0); break;
default:printf("\nYou have entered a wrong choice!!!");
}
}
}
The problem is that how do i sort the scores by score. My code seems right but doesn't work. I made a temp structure and tried to swap values but it doesn't work. Am i doing the loop wrong? Or all my code is wrong?
Here are two answers to the problem
First one sorts the nodes in the node linked list by bubble sorting them, rearranging the linked list
Second one walks the linked list, copies a pointer to each one into an array and then sorts the array by using the struct grade members, the linked list remains unchanged
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define SWAP(T,x,y) {T *p = &(x); T *q = &(y); T z = *p; *p = *q; *q = z;}
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
struct student *head=NULL;
void add(char *f, char *s, double score) {
struct student *a;
a=(struct student*)malloc(sizeof(struct student));
strcpy(a->firstname,f);
strcpy(a->lastname,s);
a->grade = score;
a->next = head;
head = a;
}
void printout(char *label) {
struct student *node;
printf("%s\n",label);
for(node=head; node !=NULL; node=node->next) {
printf("%s %s %f\n", node->firstname, node->lastname, node->grade);
}
}
int main(int argc, char ** argv){
int mark=8;
struct student *walk, *prev;
add("Bob","Smith",10);
add("Eric","Von Däniken",90);
add("Morris","Minor",91);
add("Master","Bates",9);
add("Zoe","Bodkin",20);
add("Mary","Pippin",30);
/* bubble sort */
printout("before");
prev=head;
while(mark) {
mark=0;
for(walk=head;
walk != NULL;
walk=walk->next) {
if (walk->next && walk->grade > walk->next->grade) {
/* printf("swapping %s %s\n", walk->firstname, walk->next->firstname); */
mark=1;
if (walk == head) {
struct student *v2=walk->next;
struct student *v3=walk->next->next;
SWAP(struct student *, v3->next, v2->next);
SWAP(struct student *, head, v3->next);
walk = v3;
} else {
struct student *v1=prev;
struct student *v2=walk;
struct student *v3=walk->next;
SWAP(struct student *, v3->next, v2->next);
SWAP(struct student *, v1->next, v3->next);
walk = v3;
}
}
prev=walk;
}
}
printout("after");
return 0;
}
second version, uses qsort, retains linked list order
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
struct student{
char firstname[20];
char lastname[20];
double grade;
char zipcode[10];
struct student *next;
};
struct student *head=NULL;
size_t nodecount=0;
void add(char *f, char *s, double score) {
struct student *a;
a=(struct student*)malloc(sizeof(struct student));
strcpy(a->firstname,f);
strcpy(a->lastname,s);
a->grade = score;
a->next = head;
head = a;
nodecount++;
}
static int cmpgrade(const void *p1, const void *p2) {
struct student *g1, *g2;
g1=*(struct student **)p1;
g2=*(struct student **)p2;
return g1->grade > g2->grade;
}
int main(int argc, char ** argv){
int i;
struct student *walk,**sa, **sap;
add("Bob","Smith",10);
add("Eric","Von Däniken",90);
add("Morris","Minor",91);
add("Master","Bates",9);
add("Zoe","Bodkin",20);
add("Mary","Pippin",30);
/*copy into array of pointers*/
sa=calloc(sizeof (struct student*), nodecount);
sap=sa;
for(walk=head; walk != NULL; walk=walk->next) {
*sap = walk;
sap++;
}
printf("before\n");
for (i=0; i< nodecount; i++) {
printf("%s %s %f\n", sa[i]->firstname, sa[i]->lastname, sa[i]->grade);
}
/* qsort */
qsort(sa, nodecount, sizeof (struct student *), cmpgrade);
printf("after\n");
for (i=0; i< nodecount; i++) {
printf("%s %s %f\n", sa[i]->firstname, sa[i]->lastname, sa[i]->grade);
}
return 0;
}

Resources