Topic 12 – Dynamic Memory Allocation & Linked Lists

Slides:



Advertisements
Similar presentations
CHP-5 LinkedList.
Advertisements

Dynamic memory allocation
Introduction to Linked Lists In your previous programming course, you saw how data is organized and processed sequentially using an array. You probably.
Managing Memory Static and Dynamic Memory Type Casts Allocating Arrays of Dynamic Size Resizing Block of Memory Returning Memory from a Function Avoiding.
CSCI 171 Presentation 11 Pointers. Pointer Basics.
ספטמבר 04Copyright Meir Kalech1 C programming Language Chapter 6: Dynamic Memory Allocation (DMA)
Introduction of Memory Allocation. Memory Allocation There are two types of memory allocations possible in c. Compile-time or Static allocation Run-time.
1 Objectives ❏ To understand the relationship between arrays and pointers ❏ To understand the design and concepts behind pointer arithmetic ❏ To write.
Kernighan/Ritchie: Kelley/Pohl:
Memory Allocation. Memory A memory or store is required in a computer to store programs (or information or data). Data used by the variables in a program.
POINTER Prepared by MMD, Edited by MSY1.  Basic concept of pointers  Pointer declaration  Pointer operator (& and *)  Parameter passing by reference.
Pointers Typedef Pointer Arithmetic Pointers and Arrays.
Informática II Prof. Dr. Gustavo Patiño MJ
Chapter 8 Runtime Support. How program structures are implemented in a computer memory? The evolution of programming language design has led to the creation.
Dynamic Data Structures H&K Chapter 14 Instructor – Gokcen Cilingir Cpt S 121 (July 26, 2011) Washington State University.
Topic 9 – Introduction To Arrays. CISC105 – Topic 9 Introduction to Data Structures Thus far, we have seen “simple” data types. These refers to a single.
Topic 11 – Structures and Unions. CISC105 – Topic 11 Introduction to Structures We have seen that an array is a list of the same type of elements. A structure.
Topic 9A – Arrays as Function Arguments. CISC105 – Topic 9A Arrays as Function Arguments There are two ways to use arrays as function arguments: Use an.
Topic 8 – Introduction to Pointers and Function Output Parameters.
Copyright © 2008 Pearson Addison-Wesley. All rights reserved. Chapter 13 Pointers and Linked Lists.
Pointers. Addresses in Memory When a variable is declared, enough memory to hold a value of that type is allocated for it at an unused memory location.
Linked Lists Chained nodes of information create what are called linked lists, with each node providing a link to the next node. A useful feature of linked.
CEG 221 Lesson 2: Homogeneous Data Types Mr. David Lippa.
1 CS 201 Dynamic Data Structures Debzani Deb. 2 Run time memory layout When a program is loaded into memory, it is organized into four areas of memory.
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
CS Data Structures Chapter 4 Lists.
Pointers Applications
1 Procedural Concept The main program coordinates calls to procedures and hands over appropriate data as parameters.
Prof. amr Goneid, AUC1 CSCE 110 PROGRAMMING FUNDAMENTALS WITH C++ Prof. Amr Goneid AUC Part 10. Pointers & Dynamic Data Structures.
Implementation of Linked List For more notes and topics visit: eITnotes.com.
17. ADVANCED USES OF POINTERS. Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed.
CMPSC 16 Problem Solving with Computers I Spring 2014 Instructor: Tevfik Bultan Lecture 12: Pointers continued, C strings.
Stack and Heap Memory Stack resident variables include:
Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile.
Computer Science and Software Engineering University of Wisconsin - Platteville 2. Pointer Yan Shi CS/SE2630 Lecture Notes.
1 Dynamic Memory Allocation –The need –malloc/free –Memory Leaks –Dangling Pointers and Garbage Collection Today’s Material.
Dynamic Memory Allocation. Domain A subset of the total domain name space. A domain represents a level of the hierarchy in the Domain Name Space, and.
Page 1 Data Structures in C for Non-Computer Science Majors Kirs and Pflughoeft Dynamic Memory Allocation Suppose we defined the data type: struct custrec.
Pointers: Basics. 2 What is a pointer? First of all, it is a variable, just like other variables you studied  So it has type, storage etc. Difference:
Copyright 2005, The Ohio State University 1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation.
19&20-2 Know how to declare pointer variables. Understand the & (address) and *(indirection) operators. Dynamic Memory Allocation Related Chapter: ABC.
Pointers in C Computer Organization I 1 August 2009 © McQuain, Feng & Ribbens Memory and Addresses Memory is just a sequence of byte-sized.
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 14: Pointers.
POINTERS. // Chapter 3 - Program 1 - POINTERS.CPP #include int main() { int *pt_int; float *pt_float; int pig = 7, dog = 27; float x = , y = 32.14;
Pointers in C++. Topics Covered  Introduction to Pointers  Pointers and arrays  Character Pointers, Arrays and Strings  Examples.
CNG 140 C Programming (Lecture set 12) Spring Chapter 13 Dynamic Data Structures.
1 Recall that... char str [ 8 ]; str is the base address of the array. We say str is a pointer because its value is an address. It is a pointer constant.
1 Chapter 15-1 Pointers, Dynamic Data, and Reference Types Dale/Weems.
MORE POINTERS Plus: Memory Allocation Heap versus Stack.
CCSA 221 Programming in C CHAPTER 11 POINTERS ALHANOUF ALAMR 1.
CMPSC 16 Problem Solving with Computers I Spring 2014 Instructor: Lucas Bang Lecture 11: Pointers.
Learners Support Publications Operators.
What do I need to Know For My Assignment?. C Pointer Review To declare a pointer, we use the * operator. This is similar to but different from using *
C Tutorial - Pointers CS 537 – Introduction to Operating Systems.
Pointers: Basics. 2 Address vs. Value Each memory cell has an address associated with it
You learned how to declare pointer variables how to store the address of a variable into a pointer variable of the same type as the variable how to manipulate.
Prof. Amr Goneid, AUC1 CSCE 210 Data Structures and Algorithms Prof. Amr Goneid AUC Part R2. Elementary Data Structures.
DYNAMIC MEMORY ALLOCATION. Disadvantages of ARRAYS MEMORY ALLOCATION OF ARRAY IS STATIC: Less resource utilization. For example: If the maximum elements.
Recap Resizing the Vector Push_back function Parameters passing Mechanism Primitive Arrays of Constants Multidimensional Arrays The Standard Library string.
Stack and Heap Memory Stack resident variables include:
Winter 2009 Tutorial #6 Arrays Part 2, Structures, Debugger
Pointers and Memory Overview
CSCE 210 Data Structures and Algorithms
Lecture 6 C++ Programming
Introduction to Linked Lists
Object Oriented Programming COP3330 / CGS5409
Pointers, Dynamic Data, and Reference Types
Pointers, Dynamic Data, and Reference Types
Module 13 Dynamic Memory.
Dynamic Data Structures
Presentation transcript:

Topic 12 – Dynamic Memory Allocation & Linked Lists

Static Memory Allocation So far, we have only seen static memory allocation. This means that the number of variables a program will use, and their sizes, are fixed and known when the program is written and compiled. It is possible to read through a program and calculate exactly how much memory will be required when the program is run, and how much memory each variable and/or data structure will need. CISC105 – Topic 12

Static Memory Allocation Notice that this requires that the maximum number of elements in an array must be known when the program is written. This is not practical, as the total number of variables may not be known in advance. For example, in writing a student record database program, the number of students may not be known in advance. This may result in far too much memory being allocated or not enough. CISC105 – Topic 12

Static Memory Allocation It is clear why the approach we have seen thus far is limited. We need to know how many variables the program will need in advance. If this number is too low, the program will not be able to handle the necessary data. If this number is too high, the program will waste memory, as all of the allocated memory will not be used. CISC105 – Topic 12

Dynamic Memory Allocation These disadvantages are overcome by making use of dynamic memory allocation. This refers to a program deciding at run-time how much memory to allocate. A program can call certain functions to allocate memory at any time. Therefore, the program can use input data as the basis for determining how much space to request and what type of data to store in this space. CISC105 – Topic 12

Dynamic Memory Allocation As dynamic memory allocation allows the program to make direct use of memory, it is clear that pointers must be used in some fashion. Using dynamic data structures requires the sophisticated use of pointers; thus we will briefly summarize the use of pointers we have covered thus far. CISC105 – Topic 12

A Quick Review of Pointers A pointer is a variable that holds a memory address. We can use the “*” operator to dereference a pointer. This refers to “following the pointer” to get what it is pointing to. We can pass pointers to (the addresses of) variables into functions; this allows the function to modify variables local to the calling function (call-by-reference). This allows the use of function output parameters. CISC105 – Topic 12

A Quick Review of Pointers The name of an array is simply the address of the first element of that array. Thus, we can think of an array name as a pointer to the array. A string is simply an array of characters, thus it behaves just like an array. As arrays are simply pointers to their first elements, anytime we pass an array (or string) into a function, this call is call-by-reference. The function can modify the array. CISC105 – Topic 12

Something New…Kind of. Null Pointers A pointer is a memory address. Any pointer can have a special value, NULL. This value means “does not point to anything.” If a pointer is set to NULL, it cannot be dereferenced. Any attempt to do so will cause a segmentation fault. A pointer is set to NULL using the standard assignment statement syntax: int *num1_p; num1_p = NULL; CISC105 – Topic 12

Null Pointers We can also test to see if a pointer is set to NULL, using standard comparisons. if (num1_p == NULL) { /* points to nothing */ } else { /* points to something */ } Why this is an important concept will become clear later. Null pointers are used extensively to mark the end of dynamic data structures, such as linked lists. CISC105 – Topic 12

A Quick Review of Pointers When we define structures, we can also create pointers to variables of these user-defined datatypes. Thus, we can see that pointers are simply memory addresses. They are the components of the C language used to manage memory. CISC105 – Topic 12

The malloc Function We now introduce the malloc() function. This function name is short for memory allocation. When this function is called, the program finds some unallocated space in memory. This function takes exactly one parameter, the amount of memory that the program wishes to allocate. It returns a pointer, of type void * which is the address where the memory that was just allocated begins. CISC105 – Topic 12

The malloc Function The one parameter passed into malloc is the size of the memory block we wish to allocate. This size is determined using the sizeof() function. This function takes a datatype as a parameter and returns the size of the datatype (how much space in memory one variable of that datatype occupies in memory). CISC105 – Topic 12

The malloc Function Thus, to allocate enough space in memory to store an integer, we would call malloc as: malloc(sizeof(int)); Similarly, to allocate enough space in memory to store a student_record, we would call malloc as: malloc(sizeof(student_record)); CISC105 – Topic 12

The malloc Function So, now we can allocate memory of the correct size to store a variable…how do we use it? Remember that pointers can only point to a certain datatype, i.e. an int * can only point to an integer, nothing else. malloc returns a void *. This is simply a memory address with no type. Therefore, we must cast the return value of malloc, the address of the just-allocated memory block, to the type of pointer we want to store in that memory block. CISC105 – Topic 12

The malloc Function Thus, to allocate enough space in memory to store an integer, we would call malloc as: int *int1_p; int1_p = (int *)malloc(sizeof(int)); Similarly, to allocate enough space in memory to store a student_record, we would call malloc as: student_record *TopStudent_p; TopStudent_p = (student_record *)malloc(sizeof(student_record)); CISC105 – Topic 12

The malloc Function student_record *TopStudent_p; TopStudent_p = (student_record *)malloc(sizeof(student_record)); What this call to malloc does is to allocate memory the size of one student_record. The memory address of this block of memory is stored in the pointer TopStudent. We cast this address to a student_record pointer; this indicates that we will use this block of memory as a student_record datatype. CISC105 – Topic 12

Referencing Dynamically Allocated Memory So, now we can allocate memory dynamically and obtain a pointer to a specific datatype, which will be stored in the newly allocated memory. Once this is done, values can be stored in the newly allocated memory using the pointer referencing operator “*”, just as pointers were used before. CISC105 – Topic 12

Referencing Dynamically Allocated Memory int *num1_p, *num2_p; student_record *record1_p, *record2_p; num1_p = (int *)malloc(sizeof(int)); num2_p = (int *)malloc(sizeof(int)); record1_p = (student_record *) malloc(sizeof(student_record)); record2_p = (student_record *) *num1_p = 27; *num2_p = 99; (*record1_p).letter_grade = ‘A’; strcpy(record2_p->last,”Six”); strcpy(record2_p->first,”Jeffrey”); CISC105 – Topic 12

The calloc Function The malloc function works well to allocate one variable, as we simply pass it the size of memory we need to allocate, which is easily obtained by using the sizeof function. Sometimes we wish to allocate arrays dynamically. This can be done easily using the calloc function. CISC105 – Topic 12

The calloc Function calloc is short for “contiguous allocation”. This function takes two parameters, the number of elements to allocate and the size of one element. It returns a pointer to the beginning of the newly allocated memory block, thus this pointer is equal to the address of the first element of the array. Note that this function also initializes every element of the new array to zero. CISC105 – Topic 12

The calloc Function Once an array is dynamically allocated in such a manner, it can be accessed using the same operators and other uses as a statically allocated array. This can be shown in a simple example. CISC105 – Topic 12

Dynamically Allocating Arrays with calloc int *array_of_nums; char *string; int size_of_string, number_of_nums; printf(“How many characters in the string?”); scanf(“%d”,&size_of_string); string = (char *)calloc(size_of_string, sizeof(char); scanf(“%s”,string); printf(“How many numbers?”); scanf(“%d”,&number_of_nums); array_of_nums = (int *)calloc(number_of_nums,sizeof(int)); for (count = 0; count < number_of_nums; count++) scanf(“%d”,&array_of_nums[count]); CISC105 – Topic 12

Freeing Dynamically Allocated Memory Now we have seen that malloc and calloc can be used to dynamically allocate memory. When a static variable, i.e. a local variable of a function, falls out of scope, for example, when the function it is defined in finishes (executes a return statement or the closing brace), C automatically “frees” that memory. This means the memory used for these variables is deallocated (marked as free – it can be used in the future when new memory must be allocated). CISC105 – Topic 12

Freeing Dynamically Allocated Memory This is NOT true of dynamically allocated memory. While the pointer that we set using malloc may fall out of scope and be unallocated, the memory it points to (the memory malloc allocated) is not freed. In C, it is the responsibility of the programmer to free any memory that is dynamically allocated in the program. CISC105 – Topic 12

The free Function This is done using the free function. It takes one parameter, the pointer returned by malloc. When this function is called, the memory allocated by malloc at the address contained in the pointer is deallocated (marked as free – it can be used in the future when new memory must be allocated). Thus, malloc and free can be thought of as companion functions. One allocates memory when it is needed, the other frees memory when it is no longer needed. CISC105 – Topic 12

The free Function char *string; int size_of_string; printf(“How many characters in the string?”); scanf(“%d”,&size_of_string); string = (char *)calloc(size_of_string, sizeof(char); scanf(“%s”,string); printf(“The string you typed in was:\n%s\n”, string); free(string); CISC105 – Topic 12

One Common Problem One problem is quite common when using dynamically allocated memory. Sometimes, multiple pointers can point to the same memory block. If the free function is called with one of these pointers, the memory block they both point to is unallocated. Thus, if the second pointer (not the one passed to free) is later used, the memory it points to is no longer allocated. This leads to the same problem as overstepping the bounds of an array (attempting to use memory that is not allocated). CISC105 – Topic 12

One Common Problem This statement sets string2 to string. thus string2 now points to the same place in memory as string. char *string, *string2; int size_of_string; printf(“How many characters in the string?”); scanf(“%d”,&size_of_string); string = (char *)calloc(size_of_string, sizeof(char); string2 = string; scanf(“%s”,string); printf(“The string you typed in was:\n%s\n”, string); free(string); . . . Here, we deallocate the memory string points to. As string2 points to the same memory block as string does, string2 now points to unallocated memory. DANGEROUS! CISC105 – Topic 12

The Linked List Now that we understand the concept of dynamic memory allocation, we can look at a linked list. A linked list is a data structure which is a sequence of nodes in which each node is linked, or connected to, the node following it. CISC105 – Topic 12

The Linked List Data 1 Data 1 Data 2 Next node Data 2 Data 3 Next node NO NEXT CISC105 – Topic 12

The Linked List In this linked list example, each node has two pieces of data. Each node also has a pointer to the next node. So, we need two things to form a linked list: a way to combine various datatypes and variables together into one datatype and a way to “point” to the next one of these combination datatypes. So…how can we accomplish this? CISC105 – Topic 12

The Linked List The first goal, combining various datatypes and variables into one datatype, is easily handled with a structure. The second goal, being able to “point” to the next structure is easily handled using pointers. So, we have all of the components we need in order to construct a linked list. CISC105 – Topic 12

Structures with Pointer Components We can form a linked list by defining a structure with a pointer component. typedef struct a_node { char lastname[20]; float num_grade; struct a_node *next_p; } a_node2; CISC105 – Topic 12

Structures with Pointer Components typedef struct a_node { char lastname[20]; float num_grade; struct a_node *next_p; } a_node2; The a_node name is known as a structure tag. What is does is let us use the phrase struct a_node as an alternative to using the work a_node2. We use this as the datatype for the link pointer, as the compiler has not yet reached the definition of the word a_node2. It has reached the definition of the phrase struct a_node, so we can use this as the datatype. CISC105 – Topic 12

Structures with Pointer Components typedef struct { char lastname[20]; float num_grade; a_node2 *next_p; } a_node2; This definition is illegal and will result in a compile error. When the compiler reaches the declaration of the link pointer, it does not yet know what an a_node2 is. Thus, this will cause a compiler error. CISC105 – Topic 12

Structures with Pointer Components typedef struct a_node { char lastname[20]; float num_grade; struct a_node *next_p; } a_node2; Notice that when we use this structure tag, we need to use the entire phrase struct a_node and not simply a_node. CISC105 – Topic 12

Creating a Linked List We can then setup a linked list using these structures: a_node2 *node1_p, *node2_p, *node3_p; node1_p = (a_node2 *)malloc(sizeof(a_node2)); node2_p = (a_node2 *)malloc(sizeof(a_node2)); node3_p = (a_node2 *)malloc(sizeof(a_node2)); strcpy(node1_p->lastname, “Smith”); strcpy(node2_p->lastname, “Jones”); strcpy(node3_p->lastname, “Williams”); node1_p->num_grade=90; node2_p->num_grade=20; node3_p->num_grade=100; node1_p->next_p = node2_p; node2_p->next_p = node3_p; node3_p->next_p = NULL; CISC105 – Topic 12

Creating a Linked List Node1_p Node2_p Node3_p Address = 1000 1000 1080 Address = 2370 2370 Smith Jones Williams 90 20 100 1080 2370 NULL Node1_p Node2_p Node3_p CISC105 – Topic 12

Creating a Linked List Notice that if we have the pointer to the first node in the linked list, we do not need the pointers to the other nodes, as the first node contains a pointer to the second node, the second node contains a pointer to the third node, etc. Thus, we can access any node in the linked list by starting at the first node and following the link pointers. Thus, we can think of a linked list as . . . CISC105 – Topic 12

Creating a Linked List Node1_p Address = 1000 1000 Address = 1080 Smith Jones Williams 90 20 100 1080 2370 NULL Node1_p CISC105 – Topic 12

Accessing the Data Contained in a Linked List So, we can see that node1_p points to the first node in our linked list. This first node is known as the head of the linked list. We can access the data in the first node by using the “->” operator: printf(“Name:%s\n”,node1_p->lastname); printf(“Grade:%f\n”,node1_p->num_grade); CISC105 – Topic 12

Accessing the Data Contained in a Linked List The first node also contains a pointer to the second node. Therefore, we can access this pointer and use it to access the data in the second node: printf(“Name?”); scanf(“%s”,node1_p->next_p->lastname); printf(“Grade?”); scanf(“%f”,&(node1_p->next_p->num_grade)); printf(“Name:%s”,node1_p->next_p->lastname); printf(“Grade:%f”,node1_p->next_p->num_grade); CISC105 – Topic 12

Accessing the Data Contained in a Linked List We can access the data contained in nodes past the second node in the same manner; we can simply follow the pointers to the “next node” until we arrive at the node that contains the data we want to access. Thus, if the address stored in node1_p is known by a function, that function can access every element (node) of the linked list. CISC105 – Topic 12

The Tail Node Notice in the picture that the last node in the list had its link pointer set to NULL. Thus, we can test to see if we are at the last node in a linked list. If the link pointer of a node is set to NULL, we are at the end of the list. If the link pointer of a node is not set to NULL, it will point to the next node in the list. CISC105 – Topic 12

The Tail Node In this way, the NULL pointer is used to indicate the end of the linked list. The last node in the linked list is called the tail of the list. So, the head of the list is the first node, the tail of the list is the last node, and we can tell that we are at the tail of the list if the link pointer is set to NULL. CISC105 – Topic 12

Linked List Advantages Linked lists provide a number of advantages. First and foremost, they are perfectly sized for the data that they store. When a data record is encountered, a node to store it is allocated. This defeats the limitations of arrays, where we needed to know the array size at program compile time. CISC105 – Topic 12

Linked List Advantages As linked lists are “linked” using pointers, it is easy to manipulate them. Two common operations that can be easily performed on linked lists are the insertion of a node into the list (at some point) and the deletion of a node from the list. CISC105 – Topic 12

Linked List Advantages: Inserting a Node into the List Address = 1000 1000 Address = 1080 Address = 2370 Smith Jones Williams 90 20 100 1080 8460 2370 NULL Address = 8460 Norton 98 Node1_p 2370 CISC105 – Topic 12

Linked List Advantages: Deleting a Node from the List Address = 1000 1000 Address = 1080 Address = 2370 Smith Jones Williams 90 20 100 2370 1080 2370 NULL Node1_p CISC105 – Topic 12

Linked List Traversal A common operation on a linked list is traversing a list. This means that we keep following the link pointers until we arrive at the end of the list. We can write a function that traverses the linked list we have previously made, displaying the data stored in each node. CISC105 – Topic 12

Linked List Traversal void display_list(a_node2 *head_p) { a_node2 *current_p; if (head_p == NULL) printf(“Empty List!”); else current_p = head_p; while (current_p != NULL) printf(“%s:”,current_p->lastname); printf(“%d\n”,current_p->num_grade); current_p = current_p->next_p; } CISC105 – Topic 12

Linked List Traversal We can also write a function that searches a linked list for a target data item, in this case, a last name. CISC105 – Topic 12

Linked List Traversal a_node2 * serach_list(a_node2 *head_p, char target[]) { a_node2 *current_p; for(current_p = head_p; current_p != NULL && strcmp(current_p->lastname,target) != 0; current_p = current_p->next) { } return current_p; } CISC105 – Topic 12