103
Pointers and Dynamic Memory

Memory management Arrays Dynamic memory Dynamic arrays and pointers Building a vector class

Embed Size (px)

Citation preview

Page 1: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers and Dynamic Memory

Page 2: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Memory Management

Memory managementArraysDynamic memoryDynamic arrays and pointersBuilding a vector class

Page 3: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Memory Management

Page 4: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Memory Requirements

code storage

data storage

Page 5: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Memory Management

When a program runs memory has to be allocated for its processes and its variables That is, working memory, or RAM

There needs to be a system for efficiently allocating such memory We will just consider how memory is

allocated to program data (variables)

Page 6: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

RAM

We can consider Random Access Memory (RAM) as a long sequence of bytes Starting with 0 Ending with the amount of main memory

(-1)RAM is addressable and supports

random access That is, we can go to byte 2,335,712

without having to visit all the preceding bytes

Page 7: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

RAM Illustrated

0 1 2 3 4 5 6 7 …

…107374181

6107374181

7107374181

8107374181

9107374182

0107374182

1107374182

2107374182

3

*1 GB = 1,073,741,824 bytes

Consider a computer with 1GB * of RAM

This is a fairly abstract illustration (so ignores a variety of issues)

Page 8: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Goals

As much as possible we would like to satisfy three goals when allocating memory

Time efficiency That is, we should be able to quickly find

sufficient memory to store a variableSpace efficiency

We don't want to waste memoryLow overhead

We don't want a large amount of administration

Page 9: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Stack Memory

There is a very simple way of organizing memory that meets these goals Assign memory locations to variables in

sequence▪ With no gaps

Once a variable is no longer required release the memory, allowing it to be over-written

We will call this organization the stack Or automatic memory Although the stack cannot be used for

everything

Page 10: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Stack Memory – Simple Example

Let's look at a simple example of allocating memory on a stack as described preciously

int x = 12;x = x * 3;double d = 23.567;

Notice that this example ignores all sorts of complicating issues, functions, reference variables and so on …

… 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 …

Why start at byte 3600?

No reason, it's just an arbitrary value

1236 23.567

Page 11: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Stack and Functions

Let's look at a more complex example of allocating memory That includes a main function and two

other function callsTo make the example a bit simpler I

will stop showing actual byte values And just use coloured boxes to represent

the memory allocated to variables

Page 12: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Another Example

int main(){ int r = 3; double area = circleArea(r);

double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi;}

double square(double x){ return x * x;}main memory

3 33.141

5

start of circleArea's memory

square's memory

3r radius pi

x

Page 13: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Another Example

int main(){ int r = 3; double area = circleArea(r);

double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi;}

double square(double x){ return x * x;}main memory

3 33.141

5

start of circleArea's memory

9sq_rr radius pi

Page 14: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Another Example

int main(){ int r = 3; double area = circleArea(r);

double circleArea(double radius){ double pi = 3.1415; double sq_r = square(radius); return sq_r * pi;}

double square(double x){ return x * x;}main memory

328.274

r area

Page 15: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Stack Memory

In stack memory variables for a function are allocated the next bytes in main memory From the last variable allocated space by

the same programOnce a function ends its memory is

released Remember that a function's variables

only exist while the function is executing So the memory previously allocated to a

completed function can be re-used

Page 16: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Reference Parameters

Some functions have reference parameters

There are two common reasons for doing this

Efficiency int sum(const vector<int> & v) Sums the contents of the vector

And because we want the changes made to the variable to persist after the function void square_all(vector <int> & v) Squares each value in a vector

Page 17: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Stack Problems

There is one big issue with stack memory Because memory is allocated in

sequence it is not possible to change the byte size of a variable

Strings and vectors frequently change size It is more correct to say that a string

variable may refer to strings of different sizes

A vector can change size by using its push_back method

Page 18: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Changing a Vector's Size

int main(){ vector <int> vec(3); v[0] = 1; v[1] = 2; v[2] = 3; double vid = 2.397; insert_next(3, vec);

void insert_next(int n, vector <int> & v){ for(int i=0; i < n; i++) v.push_back(i + v.size() + 1); }}

main memory

vec vid*

1 2 3 2.397

*very important double

Page 19: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Changing a Vector's Size

int main(){ vector <int> vec(3); v[0] = 1; v[1] = 2; v[2] = 3; double vid = 2.397; insert_next(vec, 3);

void insert_next(vector <int> & v, int n){ for(int i=0; i < n; i++) v.push_back(i + v.size() + 1); }}

main memory

vec v *vid*

2 3

*v is a reference to vec, it actually contains the byte

address of vec

2.397

*very important double

3n

oi

41

This is a problem, we've just corrupted the first 4 bytes of vid

Page 20: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Types Of Memory

It turns out you can divide memory into three broad categories Static Automatic Dynamic

These types of memory are typically used for different sorts of program data Although C++ gives programmers

choice over which type of memory to use

Page 21: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

data storage

data storagestatic

Storage

code storage

automatic

dynamic

Page 22: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Static Storage

Statically stored variables last for the lifetime of a program

The number of static variables does not change as a program runs So no special system is required to

maintain themStatic storage is used for global

constants And other things …

Page 23: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Automatic Storage

Function variables and parameters use automatic storage by default

Automatic variables are typically managed on a stack as we have been discussing The stack is an allocated area of

memory that grows and shrinks as functions are called

Memory is allocated sequentially (without gaps)

Page 24: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Functions and Memory

A variable defined in a function block only persists for the lifetime of that function call Unless it is declared as static

Consider what memory might be allocated when a function is running Memory required for the function’s data

and only required during the function call

Memory that is to persist beyond the lifetime of the function – we can't use the stack for this!

Page 25: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

ArraysA Digression From Memory

Page 26: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Arrays

Before looking at dynamic memory let's look at a basic data structure – the array Arrays are used to store multiple values

of the same type, much as vectors do Except that arrays are much more basic

data structures without methods (such as size)

Arrays are indexed and we can either refer to individual elements or the entire array Much like vectors

Page 27: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

What Is An Array?

An array variable is a collection of other variables You can think of an array as something

that contains variables This is important because an integer

array is not an integer, it is a collection of integers

The items stored in an array (elements) are stored sequentially in main memory Just like variables on the stack

Page 28: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Declaring Arrays

An array is declared with a type, and []s to indicate that the variable is an array The type declares the type of the array

elements

int myArray[10]

type of the data stored in

the array

brackets declare that the variable is an array

size of the array

name of the array

Page 29: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Array Indexing

The elements of the array are accessed using an index The indexes are addresses of the

elements▪ The first element always has an index of 0▪ The last index is always array size – 1

Array indexes follow the name of the array and are enclosed in []s Individual array elements are used in

exactly the same way as variables

Page 30: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Using an Array

double arr[4]; // array of 4 doubles arr[0] = 1.23; //assign 1st element arr[3] = 2.14; //assign 4th element double x = 0; x = arr[3]; //access 4th element

arr[0] arr[1] arr[2] arr[3]

the table represents main memory, each cell is an 8 byte double

x

1.23 2.14 02.14

Page 31: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Initializing Arrays

Array elements have to be given values individually This is often done in a loop

There is a special shorthand notation for initializing arrays when they are declared int arr[] = {1, 3, 7, 9}; This shorthand notation is only allowed

on the same line as the declaration

Page 32: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Array Size

An array's size must be specified when it is declared It must be a literal (i.e. a number) or A constant It can't be given using a variable

An array's size cannot change during the life of a program Arrays can therefore be allocated space

in automatic memory as their size cannot change

Page 33: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Arrays and Vectors

Arrays are not vectors, and are not classes Arrays do not have methods▪ Like size or push_back

The size of an array has to be recorded in a separate variable, and may not be changed

An array is essentially a way of referring to a collection of values of the same type Its elements

Page 34: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Arrays and Loops

Arrays are often processed using loops Allowing each element to be accessed in

turn The loop control variable is used as an

index into the array The loop ends once the array has been

processed▪ Often when the loop control variable is equal

to the size of the arrayThis is very similar to how we have

iterated through the elements of a vector

Page 35: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

For Loops

// Assume an int array named arr,// with a constant called ARR_SIZE// The loop prints the contents of arr

for (int i = 0; i < ARR_SIZE; i++){cout << arr[i] << endl;

}

The condition is i < ARR_SIZE because the last legal index is ARR_SIZE – 1Assumes the existence of a constant called ARR_SIZE, e.g. const int ARR_SIZE = 10;

Page 36: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

While Loops

// Assume an int array named arr,// with a constant called ARR_SIZE// The loop prints the contents of arr

int i = 0;while (i < ARR_SIZE){

cout << arr[i] << endl;i++;

}

A very similar loop to the for loop, we must not forget to increment the index, i

Page 37: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Size as a Constant

It is much better to define array size as a constant than to use a literal value (like 10)

If the programmer wants to change the array size this only needs to be done once Use the constant whenever the array

size is referenced, and Avoid using magic numbers!

Page 38: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Index Out of Bounds

What happens if a program attempts to access a non-legal index?

A run-time error occurs, either An illegal attempt to access a memory

location has been made (… stack is corrupted …) , or

Something less predictableAlways check that an index is legal

Between 0 and array size – 1

Page 39: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Arrays And FunctionsArray digression continues …

Page 40: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Array and Functions

Arrays can be passed to functions as parameters Parameter lists can include arrays The array type, and the fact that it is an

array must be specified in the parameter list▪ An array is specified just like any declaration

Here is the header for an array sum function int sumArray(int arr[], int sz){

Page 41: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Sum Function

// Sums the array, returning the sumint sumArray(int arr[], int sz){

int sum = 0;for (int i = 0; i < sz; i++){

sum += arr[i];}return sum;

} sz is used to specify the size of the arrayTo use this function give it the appropriate arguments

x = sumArrray(myArr, ARR_SIZE);

Page 42: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Searching Arrays

A common array task is to search an array for a particular value

int search(int arr[], int sz, int x){int result = -1;for (int i = 0; i < sz; i++){

if (arr[i] == x)return i;

}return result;

} Returns -1 (an invalid index) if the target isn't found

Returns the index of the target as soon as it is found

Page 43: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Aside – Using Arrays

Make sure that you distinguish between an array and its contents int arr[4];▪ arr is the entire array▪ arr[1] is one element of the array

The array is a sequence of integers, one element is an integer They are not interchangeable

Page 44: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Is the Array Full?

It is often important to know how much of an array is used Unassigned elements shouldn't be

processed▪ e.g. summing or calculating the average of an

arrayConsider what input a function

requires Array, and its maximum size, or Array, and current size ,or▪ i.e. the number of elements actually used

Array, maximum size, and current size

Page 45: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Returning Arrays

Arrays can be returned from a function However the obvious way of specifying

the return type is illegal▪ int[] getAnArray() { …

In addition, returning an array raises the question of how big the array is

Before continuing this we need to know more about how arrays really work

This does not work!

Page 46: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Arrays And MemoryWhat is an array really?

Page 47: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Changing Arrays

What happens if you pass an array to a function that changes the array parameter?

void doubleArray(int arr[], int sz){for (int i = 0; i < sz; i++){

arr[i] = arr[i] * 2;}

}

Notice that this is not pass by reference

Page 48: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Array Parameters

int main(){

double arr[] = {1, 2, 3};printArray(arr, ARR_SIZE);cout << "Running: void doubleArray";cout << "(double arr[], int sz);" << endl;doubleArray(arr, ARR_SIZE);printArray(arr, ARR_SIZE);return 0;

}

What has happened? The array passed to the function has changed. This does not happen with other pass-by-value parameters

Page 49: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

What's an Array?

To understand what is going on in the previous example we need to know more It's easy to think of an array as a

container, like a bookcase or a filing cabinet

But these are structures in their own right

An array is just a collection of values All of the same type, and Stored in sequence in main memory It is not an object of a class like a vector

Page 50: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

More About Arrays

An array is a sequence of bytes in main memory reserved for the array contents e.g. int arr[10]; ▪ Reserves 40 contiguous bytes▪ An int is 4 bytes, 4 * 10 = 40▪ Each element can be referenced using

indexesThe variable arr is just the address

of, or a pointer to the first array element Contains the address of the first array

element

Page 51: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

More About Indexing

Consider this assignment statement: arr[8] = 23;

To find this array element Look up the address stored in arr Multiply type size (4 for an int) by the

index Add this to the address in arr to find the

address of arr[8] element Known as an offset calculation

Page 52: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Arrays and Functions

When an array is passed to a function it is passed much like a reference parameter That is, the function is given the main

memory location of the first item in the array

But this is because array variables are addresses, not because they are inherently pass-by-reference

Because the address is passed any changes to the array are reflected outside the function If this is to be avoided make a copy in

the function

Page 53: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointer Basics

Page 54: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Arrays are Pointers

So an array variable is really just the address of the first element of the array Note that arr in int arr[10] is not of type

int It is a type that called a pointer▪ Actually a pointer to an int

Array variables are special kinds of pointer in that they are constant▪ The address stored in the pointer cannot

changeWe can explicitly declare pointer

variables

Page 55: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Variables Review

A variable is a location in main memory where data is stored The type of a variable indicates the

amount of main memory required to store the data, and

The operations that may be performed upon the data

Every variable has a byte address Its location in main memory Which is stored by the system in some

way

Page 56: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Main Memory

Main memory is a sequence of bytes

int x = 23;

Reserves 4 bytes for x in main memory and stores 23

The address of each variable is kept track of in something called a symbol table

0 220-1

0 220-1

23

Page 57: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers

A pointer is a special type of variable That stores an address rather than a

value They are called pointers as they can be

considered to point to a variable It is necessary to record the type of

data that a pointer variable points to So that the appropriate operations can

be performed on the value it points to

Page 58: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers and Types

Pointers store addresses Addresses are always the same size on

the same system▪ Often 8 bytes

So why do we have to say what type of data is going to be pointed to? To reserve enough space for the data

and To ensure that the appropriate

operations are used with the data

Page 59: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Declaring a Pointer

Pointer variable are identified by an * that follows the type in the declaration int * p;

This declares a variable called p that will point to (or refer to) an integer

Note that the type of a pointer is not the same as the type it points to p is a pointer to an int, and not an int

Page 60: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Declaring a Pointer

Previously I declared a pointer like this int * p;▪ The spaces are not necessary

You can do this int *p;

Or this int* p;

Or even this int*p;

But this is kind of ugly!

Page 61: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers and Values

The operation shown below is illegal int x = 12; int *p = x;

Remember that the type of p is an address (to an int), and not an int Addresses are actually whole numbers

but it is illegal to assign arbitrary numbers to them

This is a good thing!

error C2440: 'initializing' : cannot convert from 'int' to

'int *'

Page 62: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Address Operator

Pointers can be assigned the address of an existing variable Using the address operator, & In this way it is possible to access the

variable using a pointerThe address operator is the same

symbol as the operator to denote reference parameters But they are different operators▪ Although they perform similar tasks

Page 63: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

0 212 220-1

23

0 212 220-1

4096

23

0 212 220-1

0 212 220-1

23

Main Memory and Pointers

int x = 23;int* p = &x;

p contains the address of x& is the address of operator

Page 64: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Dereferencing

Pointers can be used to access variables But only after they have been assigned

the address of a variableTo change the value of a variable a

pointer points to the pointer has to be dereferenced Using the * operator which can be

thought of meaning the variable pointed to

Page 65: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointer Assignment

int x = 12;int *p = &x; //assign p the address of x// Use p to assign 23 to x*p = 23; //dereferences pcout << x << endl;cout << p << endl;

cout << *p << endl; value of x

value of the variable that p points to (i.e. x)

address of x

Page 66: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

The sizeof Operator

The sizeof operator allows us to find out the size of a type or variable cout << sizeof(int); cout << sizeof(‘c’); //size of a char cout << sizeof(Cylinder); //the size of a

Cylindersizeof returns a number of bytes

Page 67: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Reference Operator

The & operator is also used to create reference parameters Where a variable is passed to a function

by reference, rather than by value Reference parameters are not pointers

A reference parameter is given the address of the argument passed to the function And thereafter behaves like a normal

variable

Page 68: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Overloaded Operators

C++ tends to re-use operators The meaning can be determined by the context

The * operator multiplication: 12 * 3; declaration of a pointer: int* p; dereference: *p = 23;

The & operator address of: p = &x; pass by reference: void swap(int & x, int & y)

Page 69: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers and Assignmentint x = 12;int y = 77;int *p1 = &x; //assign p1 the address of xint *p2 = &y; //assign p2 the address of y

p1

p2

1277

x

y

Page 70: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers and Assignmentint x = 12;int y = 77;int *p1 = &x; //assign p1 the address of xint *p2 = &y; //assign p2 the address of yp1 = p2; //assigns the address in p2 to p1

p1

p2

1277

x

y

Page 71: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

1277

Pointers and Assignmentint x = 12;int y = 77;int *p1 = &x; //assign p1 the address of xint *p2 = &y; //assign p2 the address of y*p1 = *p2;

p1

p2 77

x

y

Page 72: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Why Use Pointers?

In practice we don't often use pointers like the preceding examples There is little point in making pointers to

individual integers stored on the stackPointers are key to managing

memory for objects that change size during run-time Such objects are allocated space in

another area of main memory – in dynamic memory

Page 73: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Dynamic Memory

Page 74: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Stack and Dynamic Memory

Stack memory is allocated at run time But it has a duration and size that can

be easily and correctly predictedSome data requires memory of

unknown size or duration That is, as programmers we don't know

how much memory the program will require

Such data should be stored in dynamic memory

Page 75: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Dynamic Memory

Dynamic memory allows memory usage to be determined at run-time

Allows users to decide the size of data structures like vectors and dynamic arrays

Allows space to be reserved for large objects only as it is needed

Page 76: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Uses of Dynamic Memory

There are many examples of data that is stored dynamically Vectors and dynamic arrays Reference structures such as linked lists Variable size character strings Object variables▪ Although these do not have to be stored

dynamically …

Page 77: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Why Not Use the Stack

Data that is stored dynamically may Change size, and may Persist beyond the duration of a function

It cannot therefore be stored on the stack Because stack memory is allocated

sequentially And all memory associated with a

function is released when the function ends

Page 78: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers

Data that is allocated dynamically is accessed through pointers When a new dynamic variable is created

a pointer is assigned its addressPointers point to data in dynamic

memory Pointers themselves are usually

automatic variables and therefore reside on the stack

One common use of pointers is in creating dynamic arrays

Page 79: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Dynamic ArraysAnd Back To Arrays

Page 80: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Array Size Revisited

As noted previously array size must be given a constant value And the size of an array cannot be

changed while the program is running (during run-time)

Which supports the organization of stack memory

It is possible to allocate memory at run-time From a free store of memory, called

dynamic memory

Page 81: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Dynamic Memory

Think of memory being used by a program as falling into two categories*Stack memory, the

amount to be allocated is easily managed

Dynamic memory, reserved when needed at run-time, but needs more administration to use

* In reality it’s a bit more complicated

Page 82: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Dynamic Arrays

int arrSize = 0;cout << "How big an array? ";cin >> arrSize;int* arr = new int[arrSize];

The variable is a pointer, used to store an address

Creates this array in dynamic

memoryData created in dynamic memory persists until the application is terminated, regardless of which function it was created in

Page 83: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Using Dynamic Arrays

Once a dynamic array has been created it can be used like any other array Individual array elements are accessed

using an indexA dynamic array can be passed to a

function that takes an array parameter The only difference is that a dynamic

array's address can be changed Allowing it to point to a new array

Page 84: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Deleting Arrays

Dynamic memory continues to be allocated even outside the scope in which it was created Whereas memory for a function's

parameters and variables is released when the function ends

Dynamic memory remains allocated until The application terminates, or It is explicitly released

Page 85: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

delete

Every dynamic array created by a program must also be deleted This also applies any dynamic memory

as we will see later Use delete[] to delete a dynamic array

A simple rule is that Any variable that is created using the

keyword new must be deleted by the programmer

Page 86: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Dynamic Arrays

int arrSize = 0;cout << "How big an array? ";cin >> arrSize;int* arr = new int[arrSize];// … arr is used in the program …delete[] arr;

Deallocates the dynamic memory

Indicates that an array is to be deleted

Only memory allocated with new needs to be deleted

Page 87: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Returning Arrays

An array can be returned from a function But it must be returned as a pointerint* oddArray(int sz){

int* result = new int[sz];for (int i = 0; i < sz; i++){

result[i] = i * 2 + 1;}return result;

}

arr should be deleted at some point

Use the function something like this:

int* arr = oddArray(10);

Page 88: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Returning Array Size

In the previous example an array was created in a function and then returned The size of the array was known outside

the function, and passed to the function If a function creates an array of

unknown size, the size must also be returned This may require the use of a reference

(&) parameter to access the size

Page 89: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers and Objects

Page 90: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Use Pointers ...

To refer to the same data in multiple ways For example, return a pointer to an

element in a data structureTo create data in dynamic memory

To create dynamic data (strings, vectors, ...)

To only reserve space for large objects when necessary

To create reference structures

Page 91: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Memory

Memory used by a program can be broken down into two main components

Stack memory, used to store variables in the main and other functions Stores any variable not created with new

Dynamic memory Often referred to as the free store or the

heap Stores data created with new

Page 92: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

New

Pointers can be used to create variables with no identifiers These variables are accessed using

pointersSuch variables are dynamically

allocated They are created and destroyed as the

program is running This allows, for example, vectors to be

created with the size determined at run-time▪ This is hidden from the user of the vector

Page 93: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

The NULL Pointer

Pointers store memory addresses Initially a pointer may not refer to a

memory address So does not have a meaningful value

The constant, NULL is used to indicate that a pointer's address has not been assigned NULL actually equals 0 As memory addresses are in fact whole

numbers

Page 94: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers and Classes

Pointers are frequently used with classes

Some objects can be very large Objects may contain bitmaps, or sound

files Without dynamic memory space has to

be reserved for objects that may not be used

Pointers must be dereferenced to access an object's methods

Page 95: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

New Example

int *p1 = new int; //pointer to an int// Make a new Student, default constructorint *p2 = new Student(); // Make a new Studentint *p3 = new Student(94101); *p1 = 119;int id = p2.getID();

Error! p2 is not a Student it is an address ...

... assumes the existence of a Student class ...

Page 96: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Pointers and Objects

A pointer must be dereferenced to access the methods or attributes of an object That the pointer points to

This has to be done carefully, for example: p2.displayStudent(); //error! *p2.displayStudent (); //error! (*p2).displayStudent (); //works

It is much easier to use the -> operator

Page 97: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Referring to Objects

The -> operator can be used to refer to an object's methods using a pointer Student* p = new Student(94101); p->addGrade(3, 3.33);

The -> operator is only used with pointers It should not be used with regular object

variables Use dot notation for such variables

Page 98: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Deletion

Stack (non dynamic) memory is released automatically When a function finishes execution all of

its memory is releasedDynamic memory is only released

automatically when an application ends The free store is finite Dynamically allocated memory should

be explicitly released when not required

Page 99: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Deleting Memory

The keyword delete is used to free dynamically allocated memory

When deleting a dynamic array delete must be followed by []s

Memory space that has been deallocated cannot be freed again Attempting to do this results in an error

Page 100: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

delete Operator

The delete operator is used to free memory that has been dynamically allocated int * p = new int; *p = 23; ... delete p;

Each new should have a matching delete Although often not in the same function

Page 101: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

New and Delete

int* arr = NULL;int sz = 0;cout << “Please enter size”;cin >> sz;arr = new int[sz];int* p_int = new int(12);delete p_int;delete[] arr;arr = NULL;delete[] arr;delete p_int;

frees up 4 bytesfrees up 4 bytes

frees up the 40 bytes allocated for the dynamic

array

frees up the 40 bytes allocated for the dynamic

arraysafe since arr is NULL, but

pointlesssafe since arr is NULL, but

pointlessresults in an error!

indicates that arr does not point to

anything

indicates that arr does not point to

anythingallocates space for an int

array of size sz, and returns its address which is

then assigned to arr

allocates space for an int array of size sz, and

returns its address which is then assigned to arr

Page 102: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Building a Simple Vector ClassBringing It All Toegether …

Page 103: Memory management  Arrays  Dynamic memory  Dynamic arrays and pointers  Building a vector class

Building a Vector Class

We will write a class that uses pointers and dynamic arrays to behave much like a vector

To keep things simple we will just Implement a vector of doubles rather

than a template for any type Implement push_back and size methods Start by allowing access to the vector

elements using get(index) and set(index)The example will be developed in

class