ICOM 4015 Advanced Programming Lecture 6 Dynamic Memory

  • Slides: 15
Download presentation
ICOM 4015 Advanced Programming Lecture 6 Dynamic Memory I Reading: Prof. Bienvenido Vélez 3/4/2021

ICOM 4015 Advanced Programming Lecture 6 Dynamic Memory I Reading: Prof. Bienvenido Vélez 3/4/2021 ICOM 4015 1

Dynamic Memory I Outline • What is dynamic memory? • Why dynamic memory? •

Dynamic Memory I Outline • What is dynamic memory? • Why dynamic memory? • Pointers • Pitfalls of dynamic memory management 3/4/2021 ICOM 4015 2

The address space of a program code static variables STACK activation records HEAP Dynamic

The address space of a program code static variables STACK activation records HEAP Dynamic objects 3/4/2021 ICOM 4015 3

The address space of a program code Pointer object p static variables STACK activation

The address space of a program code Pointer object p static variables STACK activation records dynamic object HEAP Dynamic objects Pointers add a level of indirection 3/4/2021 ICOM 4015 4

Dynamic Memory Summary • Pointer declaration type* variable • Pointer allocation variable = new

Dynamic Memory Summary • Pointer declaration type* variable • Pointer allocation variable = new type • Memory recycling – delete variable • Pointer dereferencing – *variable • Pointers to structures – (*variable). field = variable->field 3/4/2021 ICOM 4015 5

Example 1 - main function // sort. cc // Implements insertion sort algorithm extern

Example 1 - main function // sort. cc // Implements insertion sort algorithm extern "C" { #include <stdlib. h> } #include <iostream> #define max. Array. Length 1000 struct student { char *number; char *name; float gpa; … } // Main function main() { const long students = 10; student* a[max. Array. Length] = {0}; // Fill in array for (int i=0; i<students; i++) { a[i] = new student; fill. Student(*a[i]); } cout << "Original array: " << endl; print. Array(a, students); insertion. Sort(a, students); cout << "Sorted array: " << endl; print. Array(a, students); // recycle memory allocated for array elements for (int i=0; i<students; i++) { delete a[i]; } return 0; } 3/4/2021 ICOM 4015 6

Example 1 - Auxiliary Functions #define TYPE student* // Definitions of local auxiliary functions

Example 1 - Auxiliary Functions #define TYPE student* // Definitions of local auxiliary functions void print. Array(student* list[], long num. Elements) { for (long i=0; i<num. Elements; i++) { cout << "list[" << i << "] = " << *list[i] << endl; } } void swap(TYPE& a, TYPE& b) { TYPE temp = a; a = b; b = temp; } void insertion. Sort(TYPE list[], long num. Elements) { int comparisons = 0; for (long i=1; i<num. Elements; i++) { long j = i; while ((j>0) && (*list[j] < *list[j-1])) { comparisons ++; swap(list[j], list[j-1]); j--; } } cout << "Insertion sort comparisons = " << comparisons << endl; } 3/4/2021 ICOM 4015 7

Pitfalls of Dynamic Memory • Dereferencing non-initialized pointers • Dangling references – After delete

Pitfalls of Dynamic Memory • Dereferencing non-initialized pointers • Dangling references – After delete – The aliasing problem • Garbage generation – Assignment to non-null pointers – After function exit – Intermediate expressions • Null pointer dereference 3/4/2021 ICOM 4015 8

Dereference of non-initted pointers int f() { char *p; *p = ‘a’; // error!

Dereference of non-initted pointers int f() { char *p; *p = ‘a’; // error! . . . } LESSON Pointers must be made to point to some dynamically created object (using new) before they can be dereferenced. 3/4/2021 ICOM 4015 9

Dangling Pointers After Delete Struct student { char* name; . . . } int

Dangling Pointers After Delete Struct student { char* name; . . . } int main(){ student* me = new student; delete me; cout << me->name << endl; // error !! } LESSON A pointer to an already deleted object should never be dereferenced. It is a good idea to set a pointer to NULL right after deleting its pointing object. 3/4/2021 ICOM 4015 10

Dangling Pointers The aliasing problem struct student { char* name; . . . }

Dangling Pointers The aliasing problem struct student { char* name; . . . } int main(){ student *s 1 = new student; student* s 2 = s 1; delete s 1; // This makes s 2 dangling cout << s 2 ->name << endl; // error !! } LESSON A pointer may become dangling as a result of being aliased by another pointer. Must be careful when more than one pointer points to the same object. It is probably a good idea to avoid aliasing unless there is a good reason. 3/4/2021 ICOM 4015 11

Garbage Generation Assignment to non-null pointers int main() { int* ip; ip = new

Garbage Generation Assignment to non-null pointers int main() { int* ip; ip = new int; // ip is the ONLY ptr to new int ip = NULL; // Lost pointer to dynamic int // Object becomes inaccessible … } Lesson If you loose the last pointer to an object, the object cannot be recycled nor used. It becomes “garbage” becomes it consumes memory that can be occupied by other objects. Must make sure you delete dynamic objects before you loose all the pointers to them. Garbage generating code is also known as having memory leaks. 3/4/2021 ICOM 4015 12

Garbage Generation Local Pointers on Exit int f() { int* ip; // ip is

Garbage Generation Local Pointers on Exit int f() { int* ip; // ip is a local pointer ip = new int; // ip is the ONLY ptr to new int return 0; // Lost pointer to dynamic int // Object becomes inaccessible } Lesson If the only pointer to an object is stored in a local variable, the object will become garbage on function exit. If you want the object to survive the exit, make sure you do something to save the pointer in a non-local structure. Otherwise delete the object before exiting the function. 3/4/2021 ICOM 4015 13

Garbage Generation Intermediate Expressions int* get. Pointer(int x) { return new int(x); } int

Garbage Generation Intermediate Expressions int* get. Pointer(int x) { return new int(x); } int main() { cout << *get. Pointer(5) + *get. Pointer(6) << endl; // Here the pointer to both objects generated // by get. Pointer are never stored. They get // discarded and the objects they point to // become garbage } Lesson Intermediate expressions that have memory leaks as notoriously awkward to deal with. We will learn one nice method to deal with them when we get to talk about class constructors. 3/4/2021 ICOM 4015 14

Null Pointer Derefencing main() { int* ip = NULL; cout << *ip << endl;

Null Pointer Derefencing main() { int* ip = NULL; cout << *ip << endl; } // error LESSON It is an error (e. g. Segmentation Fault) to try to dereference a NULL pointer. 3/4/2021 ICOM 4015 15