Download presentation
Presentation is loading. Please wait.
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; }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.