Presentation is loading. Please wait.

Presentation is loading. Please wait.

- Dynamic Allocation - Linked lists

Similar presentations


Presentation on theme: "- Dynamic Allocation - Linked lists"— Presentation transcript:

1 - Dynamic Allocation - Linked lists
C Programming - Dynamic Allocation - Linked lists

2 Dynamic Allocation Array variables have fixed size, used to store a fixed and known amount of variables – known at the time of compilation This size can’t be changed after compilation However, we don’t always know in advance how much space we would need for an array or a variable We would like to be able to dynamically allocate memory

3 The malloc function void * malloc(unsigned int nBytes);
The function malloc is used to dynamically allocate nBytes in memory malloc returns a pointer to the allocated area on success, NULL on failure You should always check whether memory was successfully allocated Remember to #include <stdlib.h>

4 Example – dynamic_reverse_array – part1
#include <stdlib.h> #include <stdio.h> int main(void) { int i, n, *p; printf("How many numbers do you want to enter?\n"); scanf("%d",&n); /* Allocate an int array of the proper size */ p = (int *)malloc(n*sizeof(int)); if(p == NULL) { printf("Memory allocation failed!\n"); return 1; }

5 Why casting? The casting in y = (int *)malloc(n*sizeof(int));
is needed because malloc returns void * : void * malloc(unsigned int nbytes); The type (void *) specifies a general pointer, which can be cast to any pointer type.

6 What is this ‘sizeof’ ? The sizeof operator gets a variable or a type as an input and outputs its size in bytes: double x; s1=sizeof(x); /* s1 is 8 */ s2=sizeof(int) /* s2 is 4 */

7 Example – dynamic_reverse_array – part2
/* Get the numbers from the user */ printf("Please enter numbers now:\n"); for(i=0; i<n; i++) scanf("%d", &p[i]); /* Display them in reverse */ printf("The numbers in reverse order are - \n"); for(i=n-1; i>=0; i--) printf("%d ",p[i]); /* Free the allocated space */ free(p); return 0; }

8 Free the allocated memory segment
void free(void *ptr); We use free(p) to free the allocated memory pointed to by p If p doesn’t point to an area allocated by malloc, a run-time error occurs Always remember to free the allocated memory once you don’t need it anymore Otherwise, you may run out of memory before you know it!

9 Example – another_strcpy
int main(void) { char str1[201]; char *str2; printf("Enter a string (no more than 200 chars)\n"); scanf("%s",str1); printf("Source string:\n%s\n",str1); str2 = another_strcpy(str1); if(str2 != NULL) { printf("Destination string:\n%s\n",str2); free(str2); return 0; } return 1;

10 another_strcpy char *another_strcpy(char *src) { char *dst;
int len, i; len=strlen(src); dst=(char*)malloc(sizeof(char)*(len+1)); /* +1 - for the null */ if(dst == NULL) { printf("Memory allocation failed!\n"); return NULL; } for(i=0;i<=len;i++) /* by using <= we include the '\0' as well */ dst[i] = src[i]; return dst;

11 Exercise Implement the function my_strcat :
Input – two strings, s1 and s2 Output – a pointer to a dynamically allocated concatenation (‘shirshur’) For example: The concatenation of “hello_” and “world!” is the string “hello_world!” Write a program that accepts two strings from the user and prints their concatenation Assume input strings are no longer than a 100 chars Don’t assume anything about output string!

12 Solution - function char *my_strcat(char *str1, char *str2) {
int len1, len2; char *result; len1 = strlen(str1); len2 = strlen(str2); result = (char *)malloc( (len1+len2+1) * sizeof(char)); if(result == NULL) { printf("Allocation failed! \n”); return NULL; } strcpy(result, str1); strcpy(result+len1, str2); return result;

13 Solution - main int main() { char str1[MAX_LEN], str2[MAX_LEN];
char *cat_str; printf("Please enter two strings\n"); scanf("%100s", str1); scanf("%100s", str2); cat_str = my_strcat(str1, str2); if (cat_str == NULL) { printf("Problem allocating memory!n"); return 1; } printf("concatenation is %s\n", cat_str); free(cat_str); return 0;

14 Implementing a student package
We want to create (part of) a course-management program. We need to: Maintain a list of the participating students Keep track of their final grade Be able to add and remove students from the course And so on…

15 How will we store a student?
One possible way is using a structure, like - typedef struct Student_t { char ID[ID_LENGTH+1]; char Name[NAME_LENGTH+1]; int grade; } Student;

16 Creating a student Student NewStudent(char name[],
char ID[], int grade) { Student new_student; strcpy(new_student.Name, name); strcpy(new_student.ID, ID); new_student.grade = grade; return new_student; }

17 Storing a list of students
One way to go would be by using an array of student structures (or pointers to structures). There are problems with this – we must allocate a big-enough array before accepting students (how do we know what’s big enough?) How shall we remove students from the list without creating “holes”? How can we maintain the list sorted by grade? Insertion and deletion may be problematic

18 Linking students A better alternative might be using a linked list
typedef struct Student_t { char ID[ID_LENGTH]; char Name[NAME_LENGTH]; int grade; struct Student_t *next; /* A pointer to the next item on the list */ } Student;

19 Linked list of Students
Head Student Student Student Student 21 Haim 96 next 32 Itzik 87 next 9 Dafna 100 next 25 Kobi 90 next 1. A list is always maintained by its head - why is this enough? 2. A list ends when the next field points to NULL.

20 Linked lists - searching
! ? ? Head

21 Linked lists - insertion
Previous Next Head Insert new item:

22 Linked lists - deletion
Item to delete Previous Head

23 Creating a new kind of student
Usually when using linked lists we don’t know how many elements will be in the list Therefore we would like to be able to dynamically allocate new elements when the need arises

24 Creating a new student Student* create_student(char name[], char ID[],
int grade) { Student *std; std = (Student *)malloc(sizeof(Student)); if (std == NULL) { printf(“Memory allocation error!\n”); exit(1); } strcpy(std->Name, name); strcpy(std->ID, ID); std->grade = grade; std->next = NULL; return std;

25 Freeing students After we’re done, we need to free the memory we’ve allocated void free_list(Student *head) { Student *to_free = head; while (to_free != NULL) head = head->next; free(to_free); to_free = head; }

26 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

27 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

28 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

29 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

30 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

31 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

32 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

33 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

34 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

35 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

36 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

37 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

38 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

39 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

40 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

41 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

42 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

43 Freeing students to_free head NULL while (to_free != NULL) {
head = head->next; free(to_free); to_free = head; } to_free head NULL

44 Adding a student Adding a student to a list can be done in such a way that the list remains sorted by grade We will implement this in a separate function See Student_Package.c

45 Adding a student Previous Next Head Insert new item:

46 Adding a student - 2 Next Head Head

47 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

48 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

49 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

50 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

51 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

52 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

53 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

54 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

55 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

56 Adding a student – mid list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 75 95 80 70 60 head

57 Adding a student – mid list
if (previous_std == NULL) { to_add->next = head; return to_add; } previous_std->next = to_add; to_add->next = next_std; return head; next_std previous_std to_add 75 95 80 70 60 head

58 Adding a student – mid list
if (previous_std == NULL) { to_add->next = head; return to_add; } previous_std->next = to_add; to_add->next = next_std; return head; next_std previous_std to_add 75 95 80 70 60 head

59 Adding a student – mid list
if (previous_std == NULL) { to_add->next = head; return to_add; } previous_std->next = to_add; to_add->next = next_std; return head; next_std previous_std to_add 75 95 80 70 60 head

60 Adding a student – mid list
if (previous_std == NULL) { to_add->next = head; return to_add; } previous_std->next = to_add; to_add->next = next_std; return head; next_std previous_std to_add 75 95 80 70 60 head

61 Adding a student – start list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 100 95 80 70 60 head

62 Adding a student – start list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 100 95 80 70 60 head

63 Adding a student – start list
if (previous_std == NULL) { to_add->next = head; return to_add; } previous_std->next = to_add; to_add->next = next_std; return head; next_std previous_std to_add 100 95 80 70 60 head

64 Adding a student – start list
if (previous_std == NULL) { to_add->next = head; return to_add; } previous_std->next = to_add; to_add->next = next_std; return head; next_std previous_std to_add 100 95 80 70 60 head

65 Adding a student – start list
if (previous_std == NULL) { to_add->next = head; return to_add; } previous_std->next = to_add; to_add->next = next_std; return head; next_std previous_std to_add 100 95 80 70 60 head

66 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

67 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

68 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

69 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

70 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

71 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

72 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

73 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

74 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

75 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

76 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

77 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

78 Adding a student – end list
next_std = head; while (to_add->grade < next_std->grade) { if (next_std->next == NULL) next_std->next = to_add; return head; } previous_std = next_std; next_std = next_std->next; next_std previous_std to_add 60 95 80 70 head

79 Exercise Download Student_Package.c and implement find_student, which receives a list and an ID number and returns a pointer to a student whose ID matches or NULL if no such student is found. Student *find_student(Student *head, char id[]); Hint: Use strcmp from string.h

80 Including files We can #include our own files in our program
Say you wrote a file with some list functions called MyList.c You can include it in your program myProg.c by writing #include “MyList.c” This works given that both files reside in the same directory

81 Solution /* find a student whose id matches the given id number */
Student *find_student(Student *head, char id[]) { Student *to_search = head; /* Start from head of list */ while (to_search != NULL) /* go over all the list */ if (strcmp(to_search->ID, id) == 0) /* same id */ return to_search; to_search = to_search->next; } /* If we're here, we didn't find */ return NULL;

82 Removing a student We would like to be able to remove a student by her/his ID. The function that performs this is (surprisingly) remove_student See Student_Package2.c

83 Removing a student Previous Current Head

84 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

85 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

86 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

87 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

88 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

89 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

90 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

91 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

92 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

93 Removing a student – mid list
cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 53621 cur last 14525 74823 53621 25773 head

94 Removing a student – mid list
if (last == NULL) head = head->next; else last->next = cur->next; /* Free the student */ free(cur); return head; 53621 cur last 14525 74823 53621 25773 head

95 Removing a student – mid list
if (last == NULL) head = head->next; else last->next = cur->next; /* Free the student */ free(cur); return head; 53621 cur last 14525 74823 53621 25773 head

96 Removing a student – mid list
if (last == NULL) head = head->next; else last->next = cur->next; /* Free the student */ free(cur); return head; 53621 cur last 14525 74823 53621 25773 head

97 Removing a student – mid list
if (last == NULL) head = head->next; else last->next = cur->next; /* Free the student */ free(cur); return head; 53621 cur last 14525 74823 25773 head

98 Removing a student – start list
ID cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 14525 cur last 14525 74823 53621 25773 head

99 Removing a student – start list
ID cur = head; while (strcmp(cur->ID, ID) != 0) { last = cur; cur = cur->next; if (cur==NULL) return head; } 14525 cur last 14525 74823 53621 25773 head

100 Removing a student – start list
ID if (last == NULL) head = head->next; else last->next = cur->next; /* Free the student */ free(cur); return head; 14525 cur last 14525 74823 53621 25773 head

101 Removing a student – start list
ID if (last == NULL) head = head->next; else last->next = cur->next; /* Free the student */ free(cur); return head; 14525 cur last 14525 74823 53621 25773 head

102 Removing a student – start list
ID if (last == NULL) head = head->next; else last->next = cur->next; /* Free the student */ free(cur); return head; 14525 cur last 14525 74823 53621 25773 head

103 Removing a student – start list
ID if (last == NULL) head = head->next; else last->next = cur->next; /* Free the student */ free(cur); return head; 14525 cur last 74823 53621 25773 head

104 Exercise Add a change_grade function to student_package2. The function should take as parameters the head of the list, the ID whose grade we’d like to change, and the new grade. Remember that the list must stay sorted! Hint – Create a new student with the same name, ID as the old one, with the new grade. Then remove the old student from the list and add the new one using the existing functions

105 solution /* Change a grade for a student */
Student *change_grade(Student *head, char id[],int new_grade) { /* First, check that the student exists */ Student *student=find_student(head,id); if (student==NULL) return NULL; /* Create a new student node with new grade*/ new_student=create_student(student->id,student->name,new_grade); if (new_student==NULL) /* Remove student with old grade from list */ head=remove_student(head,id); head=add_student(head,new_student); /* add student with new grade to list */ return head; }


Download ppt "- Dynamic Allocation - Linked lists"

Similar presentations


Ads by Google