Dynamic Allocation Review Structure and list processing Lectures 18 & 19 26.3.2001. and 27.3.2001 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Dynamic allocation: review Variables in C are allocated in one of 3 spots: the run-time stack : variables declared local to functions are allocated during execution the global data section : Global variables are allocated here and are accessible by all parts of a program. the heap : Dynamically allocated data items malloc, calloc, realloc manage the heap region of the mmory. If the allocation is not successful a NULL value is returned. 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Bad Pointers When a pointer is first allocated, it does not have a pointee. The pointer is uninitialized or bad. A dereference operation on a bad pointer is a serious runtime error. Each pointer must be assigned a pointee before it can support dereference operations. int * numPtr; Every pointer starts out with a bad value. Correct code overwrites the bad value. 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Example pointer code. int * numPtr; int num = 42; numPtr = # num = malloc (sizeof (int)); *num = 73; 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur int a=1, b=2, c=3; int *p, *q; a 1 xxx p b 2 xxx q c 3 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur p = &a ; q = &b ; a 1 p b 2 q c 3 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur c = *p ; p = q ; *p = 13 ; a 1 p b 13 q c 1 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Bad pointer Example void BadPointer () { int *p; *p = 42; } int * Bad2 () { int num, *p; num = 42; p = # return p; p x x x X 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur A function call malloc(size) allocates a block of mrmory in the heap and returns a pointer to the new block. size is the integer size of the block in bytes. Heap memory is not deallocated when the creating function exits. malloc generates a generic pointer to a generic data item (void *) or NULL if it cannot fulfill the request. Type cast the pointer returned by malloc to the type of variable we are assigning it to. free : takes as its parameter a pointer to an allocated region and de-allocates memory space. 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Dynamic memory allocation: review typedef struct { int hiTemp; int loTemp; double precip; } WeatherData; main () { int numdays; WeatherData * days; scanf (“%d”, &numdays) ; days=(WeatherData *)malloc (sizeof(WeatherData)*numdays); if (days == NULL) printf (“Insufficient memory”); ... free (days) ; } 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Self-referential structures Dynamic data structures : Structures with pointer members that refer to the same structure. Arrays and other simple variables are allocated at block entry. But dynamic data structures require storage management routine to explicitly obtain and release memory. 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Why linked lists ? A linked list is a dynamic data structure. It can grow or shrink in size during the execution of a program. It can be made just as long as required. It does not waste memory space. Linked lists provide flexibility in allowing the items to be rearranged efficiently. Insert an element. Delete an element. 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Self-referential structures struct list { int data ; struct list * next ; } ; The pointer variable next is called a link. Each structure is linked to a succeeding structure by next. 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Pictorial representation A structure of type struct list data next The pointer variable next contains either an address of the location in memory of the successor list element or the special value NULL defined as 0. NULL is used to denote the end of the list. 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur struct list a, b, c; a.data = 1; b.data = 2; c.data = 3; a.next = b.next = c.next = NULL; a b c 1 NULL 2 NULL 3 NULL data next data next data next 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Chaining these together a.next = &b; b.next = &c; a b c 1 2 3 NULL data next data next data next What are the values of : a.next->data a.next->next->data 2 3 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Linear Linked Lists A head pointer addresses the first element of the list. Each element points at a successor element. The last element has a link value NULL. 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Header file : list.h #include <stdio.h> #include <stdlib.h> typedef char DATA; struct list { DATA d; struct list * next; }; typedef struct list ELEMENT; typedef ELEMENT * LINK; 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Storage allocation LINK head ; head = malloc (sizeof(ELEMENT)); head->d = ‘n’; head->next = NULL; creates a single element list. head n NULL 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Storage allocation head->next = malloc (sizeof(ELEMENT)); head->next->d = ‘e’; head->next->next = NULL; A second element is added. head n e NULL 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Storage allocation head->next=>next = malloc (sizeof(ELEMENT)); head->next->next->d = ‘e’; head->next->next-> = NULL; We have a 3 element list pointed to by head. The list ends when next has the sentinel value NULL. head n e w NULL 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur List operations Create a list Count the elements Look up an element Concatenate two lists Insert an element Delete an element 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Produce a list from a string (recursive version) #include “list.h” LINK StrToList (char s[]) { LINK head ; if (s[0] == ‘\0’) return NULL ; else { head = malloc (sizeof(ELEMENT)); head->d = s[0]; head->next = StrToList (s+1); return head; } 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
list from a string (iterative version) #include “list.h” LINK SToL (char s[]) { LINK head = NULL, tail; int i; if (s[0] != ‘\0’) { head = malloc (sizeof(ELEMENT)); head->d = s[0]; tail = head; for (i=1; s[i] != ‘\0’; i++) { tail->next = malloc(sizeof(ELEMENT)); tail = tail->next; tail->d = s[i]; } tail->next = NULL; return head; 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur 1. A one-element list head 4. after assigning NULL A ? tail head A B NULL 2. A second element is attached head tail A ? ? tail 3. Updating the tail head A B ? tail 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
/* Count a list recursively */ int count (LINK head) { if (head == NULL) return 0; return 1+count(head->next); } 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur /* Count a list iteratively */ int count (LINK head) { int cnt = 0; for ( ; head != NULL; head=head->next) ++cnt; return cnt; } void LengthTest (char a[]) { int len; LINK list; list = StrToList (a); int len = count (list); } 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Stack Heap LengthTest() a list n e w NULL len 98790 count () cnt head 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Stack Heap LengthTest() a list n e w NULL len 98790 count () cnt 1 head 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Stack Heap LengthTest() a list n e w NULL len 98790 count () cnt 2 head 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Stack Heap LengthTest() a list n e w NULL len 98790 count () cnt 3 head 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur /* Print a List */ void PrintList (LINK head) { if (head == NULL) printf (“NULL”) ; else { printf (“%c --> “, head->d) ; PrintList (head->next); } 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
/* Concatenate two Lists */ void concatenate (LINK ahead, LINK bhead) { if (ahead->next == NULL) ahead->next = bhead ; else concatenate (ahead->next, bhead); } 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Insertion Insertion in a list takes a fixed amount of time once the position in the list is found. Before Insertion p2 p1 A C q B 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Insertion /* Inserting an element in a linked list. */ void insert (LINK p1, LINK p2, LINK q) { p1->next = q; q->next = p2; } After Insertion p2 p1 A C q B 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Deletion Before deletion p 1 2 3 p->next = p->next->next; garbage p After deletion 1 2 3 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Deletion (free memory) Before deletion p 1 2 3 q = p->next; p->next = p->next->next; p After deletion 1 2 3 q free (q) ; 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Delete a list and free memory /* Recursive deletion of a list */ void delete_list (LINK head) { if (head != NULL) { delete_list (head->next) ; free (head) ; /* Release storage */ } 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Insert an element into a sorted list LIST insert ( LIST head, LIST newnode) { LIST cur ; if ((head == NULL) || (newnode->d < head->d)) { newnode->next = head; return newnode; } cur = head; while ((cur->next != NULL) && (cur->next->d < newnode->d)) cur = cur->next; newnode->next = cur->next; cur->next = newnode; return head ; 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur InsertSort() LINK InsertSort (LINK head) { LINK result = NULL; LINK cur = head; LINK next; while (cur != NULL) { next = cur->next; result = insert (result, cur) ; cur = next; } return result; 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Delete an element from a sorted list LIST delete ( LIST head, DATA d) { LIST prev, temp, curr = head; while ((curr != NULL) && (curr->d < d)) { prev = curr ; curr = curr->next; } if (curr->d == d) { temp = curr ; prev->next = curr->next; free (temp); return head ; 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Assignment:Reverse a list head 1 2 3 4 head 1 2 3 4 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur
Sudeshna Sarkar, CSE, IIT Kharagpur Doubly linked list A B C Assignment : Insertion, deletion in a doubly linked list 26-27.3.2001. Sudeshna Sarkar, CSE, IIT Kharagpur