Download presentation
Presentation is loading. Please wait.
Published byRůžena Procházková Modified over 5 years ago
1
COP 3330 Object-oriented Programming in C++
Dynamic Memory Allocation Spring 2019
2
Memory Allocation Static (compile time) memory allocation
Memory for the named variables is allocated by the compiler in stacks The exact size and type of storage must be known a priori The size of an array has to be constant Dynamic memory allocation Memory allocated during runtime is placed in a program segment known as the heap The compiler does not need to know the exact size and number of items to be allocated Pointers are crucial
3
Stack Special region of computer memory that stores temporary variables in each function Every time a function declares a new variable, it is "pushed" onto the stack Every time a function exits, all of the variables pushed onto the stack by that function, are “popped" (freed, and hence lost forever) A common bug in C++ programming is attempting to access a variable that was created on the stack inside some function, from a place in your program outside of that function (i.e. after that function has exited)
4
Stack #include <iostream> using namespace std; double multiplyByTwo (double input) { double twice = input * 2.0; return twice; } int main () int age = 30; double salary = ; double myList[3] = {1.2, 2.3, 3.4}; cout << "double your salary is “ << multiplyByTwo(salary)) << endl; return 0;
5
Heap A more free-floating region of memory (and is larger) that is not managed automatically for you Use new and delete to manage heap memory Caution: memory leak! Use pointers to access memory on the heap a special data type that stores addresses in memory instead of storing actual values No size restrictions on variable size (apart from the obvious physical limitations of your computer) Variables created on the heap are accessible by any function, anywhere in your program Heap variables are essentially global in scope
6
Heap #include <iostream> double *multiplyByTwo (double *input) { double *twice = new double; *twice = *input * 2.0; return twice; } int main () int *age = new int; *age = 30; double *salary = new double; *salary = ; double *myList = new double [3]; myList[0] = 1.2; myList[1] = 2.3; myList[2] = 3.4; double *twiceSalary = multiplyByTwo(salary); delete age; delete salary; delete[] myList; delete twiceSalary; return 0;
7
Stack vs. Heap Stack Space is managed efficiently by CPU, memory will NOT become fragmented Grows and shrinks as functions push and pop local variables NO need to manage the memory yourself, variables are allocated and freed automatically Very fast access Has size limits (OS-dependent) Stack variables only exist while the function that created them is running Variables cannot be resized
8
Stack vs. Heap Heap Variables can be accessed globally
NO limit on memory size Variables can be resized (Relatively) Slower access No guaranteed efficient use of space, memory may become fragmented over time as blocks of memory are allocated, then freed You must manage memory (you're in charge of allocating and freeing variables)
9
Dynamic Memory Allocation
Can allocate memory at run time But, cannot create new variables names at run time Thus, there are two steps in dynamic allocation Allocate the space use the unary operator, new, followed by the type being allocated new returns the starting address of the allocated space Store its address in a pointer (so that the space can be accessed) int* p = new int; int size = 40; // dynamically allocates an array of 40 ints int * list = new int[size]; float* numbers = new float[size+10];
10
Dynamic Memory Access For single items, dereference the pointer to reach a dynamically created target, using the * operator For dynamically created arrays, you can use either pointer-offset notation, or standard bracket notation int *p = new int; *p = 10; // assigns 10 to the dynamic integer cout << *p; // prints 10 double *numList = new double[size]; for (int i = 0; i < size; i++) numList[i] = 0; numList[5] = 20; *(numList + 7) = 15; // same as numList[7]
11
Dynamic Memory Deallocation
Free up the dynamically allocated space by programmers when it is of no use Use the unary operator, delete Note that the name ptr can be reused To deallocate a dynamic array, use this form delete[] name_of_pointer We do not want list to point to deallocated memory space int *ptr = new int; delete ptr; // free up the space pointed by ptr ptr = new int[10]; int *list = new int[40]; delete[] list; // deallocate the array list = 0; // reset the pointer to null
12
Memory Leak You fail to deallocate dynamically allocated memory…
list = new int[40]; // first allocation // no deallocation // ………… // you forgot to delete[] list list = new int[10]; // second allocation
13
Dynamically Resizing I created an array with an initial size of , say, 100. Later on, I recognize that 100 is not sufficient, and I wanna resize the array with a larger size. How? int *list = new int[size]; // create a bigger temp array int *temp = new int[2*size]; // item-wise copy for (int i = 0; i < size; i++) temp[i] = list[i]; delete [] list; // free up the old memory // make list point to the new memory location list = temp;
14
Dynamically Resizing list Item-wise copy temp list
15
Dynamic Allocation of Objects
Objects can be dynamically allocated as well To deallocate Fraction *fp1, *fp2, *flist; // uses default constructor fp1 = new Fraction; fp2 = new Fraction(3,4); // flist is dynamic array of 20 Fraction objects with default constructor for each flist = new Fraction[20]; delete fp1; delete fp2; delete [] flist;
16
Dot Operator (.) cs. Arrow Operator (->)
A dot operator requires an object name objectName.memberName // can be data or function An arrow operator works with object pointers objectPointer->memberName // data or function You need to dereference an object pointer before using the dot operator (*fp1).show(); For pointers to dynamically allocated arrays of objects, arrow operator usually is not needed flist[3].show(); // flist is a pointer; flist[3] is an object flist[3]->show(); // INCORRECT
17
Dynamic Memory Allocation in Classes
A motivation scenario Suppose we want an array as a member data Don’t want a fixed upper bound on the size Real-world examples: shopping transactions in Walmart; visit traces on youtube.com; query logs on Google …… Solution Only embed the array pointer in classes Declare array pointers as member data Always initialize pointers in the constructors The constructor might dynamically allocate spaces (via new) and assign them to pointers The array dynamically grows (or shrinks) adaptively Cleanup (via delete) dynamically allocated space in destructor Can happen in regular member functions
18
Code Review: the PhoneBook Database
Entry Class Represents a single entry in a phone book Uses c-strings (null-terminated character arrays) to store names, addresses, and phone numbers Directory class Stores an array of Entry objects in a dynamic fashion Provides services add, delete, modify, search, and display entries Dynamically resize the array of Entries
19
More Details in PhoneBook
In Entry class, we overload << and >> Use getline()to get a string containing spaces (up to newline) In Directory class, we grow entrylist if necessary void Directory::growBad() { maxSize = currentSize + 5; Entry newList[maxSize]; for (int j = 0; j < currentSize; j++) newList[j] = entryList[j]; delete [] entryList; entryList = newList; }
20
Questions
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.