14
CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations • the capacity is fixed at MAX_SIZE elements • to change capacity, we change MAX_SIZE in the header • then we recompile the program – not pretty! We get around this using dynamic memory allocation • memory is given to an object at run-time • each object gets what it needs as it needs it

CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

Embed Size (px)

Citation preview

Page 1: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 1

Dynamic memory allocation

Our first IntVector class has some serious limitations

• the capacity is fixed at MAX_SIZE elements

• to change capacity, we change MAX_SIZE in the header

• then we recompile the program – not pretty!

We get around this using dynamic memory allocation

• memory is given to an object at run-time

• each object gets what it needs as it needs it

• dynamic memory requires the use of C++ pointers

Page 2: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 2

Pointers

A pointer is a data type whose value is the address of an object in memory

char* charPtr;char myChar = ‘A’;

We “point to” an object using the & or “address of” operator:

charPtr = &myChar;

We can change the value of myChar indirectly using the * or “dereferencing” operator:

*charPtr = ‘B’;

charPtr myChar

‘A’

charPtr myChar

‘B’

charPtr myChar

‘A’???

Page 3: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 3

charPtr char2char1

‘B’‘A’

charPtr char2char1

‘B’‘C’

Constant pointers and constant objects

char char1 = ‘A’; char char2 = ‘B’;char* const charPtr = &char1;

• the variable charPtr is a constant pointer to char

• the address in charPtr must be defined by initialization

• the address in charPtr cannot be changed afterward

charPtr = &char2;

• you can change the object pointed to

*charPtr = ‘C’;

Page 4: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 4

Pointers to constant objects

char char1 = ‘A’; const char char2 = ‘B’;const char* charPtr = &char1;

• the variable charPtr is a pointer to a constant char

• the address in charPtr can be changed any time

• the character pointed to cannot be changed

*charPtr = ‘C’; char2 = ‘D’;

• you can change the object pointed to and char1 itself

charPtr = &char2; char1 = ‘E’;

charPtr char2char1

‘B’‘A’

charPtr char2char1

‘B’‘E’

Page 5: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 5

Reference typeschar myChar = ‘A’;

char myChar = ‘B’;char& charRef1 = myChar1;

const char& charRef2 = myChar2;

• “like” a constant pointer, but better!

• charRef1 is a reference to the character myChar1

• it stores the address of the variable that it is referencing

• this address cannot be changed once it has been assigned

• automatic dereference (no * operator)

charRef1 = charRef2;

• but not for a constant reference

charRef2 = ‘C’;

charRef1 myChar1

‘A’

charRef2 myChar2

‘B’

charRef2 myChar2

‘B’

charRef1 myChar1

‘B’

Page 6: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 6

Reference parameters

Reference variables are often used as function parameters

• formal parameter become references to actual parameters

• (more about paramter-passing in a future lecture)

void swap( int& num1, int& num2 ){ int temp; temp = num1; num1 = num2; num2 = temp;}

int x = 2, y = 5;swap( x, y );

Page 7: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 7

Dynamic memory allocation (after learning pointers)

C++ has three kinds of variables:

• automatic variables allocated and de-allocated as needed

• static variables allocated for the lifetime of the execution

• dynamic variables allocated and de-allocated explicitly during execution as specified by the program

Dynamically memory allocation allows:

• memory efficiently (use only what you need)

• array (and object) sizes that vary at run time

• more sophisticated data structures and algorithms

Page 8: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 8

The new operator

new returns the address of a newly allocated object

int* intPtr;

intPtr = new int;

We can also allocate an array of integers:

int capacity;

cout << “How many integers do you want to store?\n”;cin >> capacity;int* data = new int[ capacity ];for( int index = 0; index < capacity; index++ ) cin >> data[ index ];

intPtr

data

???

???

???

???

Page 9: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 9

Garbage collection

Dynamic memory must be released when no longer required

• some languages have automatic garbage collection

• C++ requires explicit garbage collection by the program

• memory is released using the delete operator:

delete intPtr;

delete[] data;

• delete operator does not delete the pointer

• it releases the memory to which the pointer points

• delete operator will not change the pointer

• it still points to the memory that was just released!

• this is a problem

Page 10: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 10

Dangling pointers

An illegal pointer dereference results if the pointer is:

• not initialized (it could point anywhere)

• NULL (its value is zero so it points nowhere)

• referencing an object that no longer exists (dangling pointer)

• referencing outside the object it points to

Pointer arithmetic causes the last case:

int* p = new int[3];

*(p + 4) = p[5];

• both attempts dereference outside the dynamic array

• so they are illegal pointer dereferences

Page 11: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 11

Avoiding dangling pointers

After using the delete operator:

• it is often a good idea to set the corresponding pointer to 0

• the built-in value NULL is equal to zero

delete intptr;intptr = NULL;

• this avoids accidentally dereferencing a dangling pointer

A pointer whose value is NULL is a null pointer

• we often use a “ground” symbol to denote a NULL pointer

intptr

Page 12: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 12

How to avoid dangling pointers•release memory only when there is only one pointer to it!

int* intPtr1;int* intPtr2;

intPtr1 = new int;

*intPtr1 = 7;

intPtr2 = intPtr1;

delete intPtr1;

intPtr1 = NULL;

intPtr2intPtr1

7

intPtr2intPtr1

??????

intPtr2intPtr1

???

intPtr2intPtr1

???

intPtr2intPtr1

??? ???

intPtr2intPtr1

7 ???

Page 13: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 13

Memory leaks

If there is no pointer pointing to a dynamically allocated block of memory, there is a memory leak

int* intPtr;

intPtr = new int;

*intPtr = 7;

intPtr = new int;

*intPtr = 5;

intPtr

???

intPtr

7

intPtr

7

5

Page 14: CPSC 252 Dynamic Memory Allocation Page 1 Dynamic memory allocation Our first IntVector class has some serious limitations the capacity is fixed at MAX_SIZE

CPSC 252 Dynamic Memory Allocation Page 14

Invoking delete with and without the []

What memory is released when a pointer is to an array?

int* data = new int[10];

delete [] data;

• delete operator releases all 10 words of memory

int* data = new int[10];

delete data;

• delete operator still releases all 10 words of memory

• but only one destructor is invoked (for the first object)

The only difference is whether 1 or 10 destructors are called