150 likes | 165 Views
ICOM 4015 Advanced Programming. Lecture 11 Dynamic Memory I Reading: Chapter 5. Prof. Bienvenido Vélez. Dynamic Memory II Outline. What is dynamic memory? Why dynamic memory? Pointers Pitfalls of dynamic memory management. STACK activation records. HEAP Dynamic objects.
E N D
ICOM 4015 Advanced Programming Lecture 11 Dynamic Memory I Reading: Chapter 5 Prof. Bienvenido Vélez ICOM 4015
Dynamic Memory II Outline • What is dynamic memory? • Why dynamic memory? • Pointers • Pitfalls of dynamic memory management ICOM 4015
STACK activation records HEAP Dynamic objects The address space of a program code static variables ICOM 4015
STACK activation records HEAP Dynamic objects The address space of a program code Pointer object static variables p dynamic object ICOM 4015
Dynamic MemorySummary • Pointer declaration type* variable • Pointer allocation variable = newtype • Memory recycling • deletevariable • Pointer dereferencing • *variable • Pointers to structures • (*variable).field = variable->field ICOM 4015
Example 1 - main function // sort.cc // Implements insertion sort algorithm extern "C" { #include <stdlib.h> } #include <iostream> #define maxArrayLength 1000 struct student { char *number; char *name; float gpa; … } // Main function main() { const long students = 10; student* a[maxArrayLength] = {0}; // Fill in array for (int i=0; i<students; i++) { a[i] = new student; fillStudent(*a[i]); } cout << "Original array:" << endl; printArray(a, students); insertionSort(a, students); cout << "Sorted array:" << endl; printArray(a, students); // recycle memory allocated for array elements for (int i=0; i<students; i++) { delete a[i]; } return 0; } ICOM 4015
Example 1 - Auxiliary Functions #define TYPE student* // Definitions of local auxiliary functions void printArray(student* list[], long numElements) { for (long i=0; i<numElements; i++) { cout << "list[" << i << "] = " << *list[i] << endl; } } void swap(TYPE& a, TYPE& b) { TYPE temp = a; a = b; b = temp; } void insertionSort(TYPE list[], long numElements) { int comparisons = 0; for (long i=1; i<numElements; 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; } ICOM 4015
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 ICOM 4015
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. ICOM 4015
Dangling PointersAfter 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. ICOM 4015
Dangling PointersThe aliasing problem struct student { char* name; . . . } int main(){ student *s1 = new student; student* s2 = s1; delete s1; // This makes s2 dangling cout << s2->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. ICOM 4015
Garbage GenerationAssignment 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. ICOM 4015
Garbage GenerationLocal 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. ICOM 4015
Garbage GenerationIntermediate Expressions int* getPointer(int x) { return new int(x); } int main() { cout << *getPointer(5) + *getPointer(6) << endl; // Here the pointer to both objects generated // by getPointer 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. ICOM 4015
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. ICOM 4015