Dynamic Memory Allocation - members.shaw.ca

clippersdogheartedSoftware and s/w Development

Dec 14, 2013 (3 years and 7 months ago)

75 views

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

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’

???

CPSC 252




Dynamic Memory Allocation


Page
3

charPtr

char2

char1

‘B’

‘A’

charPtr

char2

char1

‘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’;


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

char2

char1

‘B’

‘A’

charPtr

char2

char1

‘B’

‘E’

CPSC 252




Dynamic Memory Allocation


Page
5

Reference types

char 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’

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 );

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

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

???

???

???

???

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

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

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

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;




intPtr2

intPtr1

7

intPtr2

intPtr1

???

???

intPtr2

intPtr1

???

intPtr2

intPtr1

???

intPtr2

intPtr1

???

???

intPtr2

intPtr1

7

???

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

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