Pointers and Dynamic Memory Allocation - Institute … and Pointers oWhen we declare a variable some...

71
Pointers and Dynamic Memory Allocation ALGORITHMS & DATA STRUCTURES 9 TH SEPTEMBER 2014

Transcript of Pointers and Dynamic Memory Allocation - Institute … and Pointers oWhen we declare a variable some...

Pointers and Dynamic Memory AllocationALGORITHMS & DATA STRUCTURES

9TH SEPTEMBER 2014

Last weekIntroduction

◦ This is not a course about programming: It’s is about puzzling.

◦ well..

ALGORITHMS AND DATA STRUCTURES 2

Donald Knuth◦ “Science is what we understand well enough to explain to

a computer.”

◦ “Beware of bugs in the above code; I have only proved it correct, not tried it.”

Algorithm

◦ Algorithm = Human (high-level) way of teaching a computer what to do to solve a problem

◦ An algorithm is a well-defined procedure which takes an input value and returns an output value

ALGORITHMS AND DATA STRUCTURES 3

C++

◦ Very powerful

◦ Bizarre syntax

◦ But this is NOT a C++ course.

4ALGORITHMS AND DATA STRUCTURES

PointersPointers

◦ Powerful feature of C++

◦ One of the most difficult to master

◦ Essential for construction of interesting (recursive) data structures, e.g. lists and trees.

5ALGORITHMS AND DATA STRUCTURES

Addresses and PointersoWhen we declare a variable some memory is allocated for it. The memory location can be referenced through the identifier of the variable.

oThus, we have two properties for any variable : its address and its data value.

oThe address of the variable can be accessed through the referencing operator &. &i gives the memory location where the data value for i is stored

oAddresses can be displayed, e.g., by using coutoAddresses displayed in HEXADECIMAL

6ALGORITHMS AND DATA STRUCTURES

Example#include <iostream.h>

void main( ) {

int data = 100;

float value = 56.47;

cout << data << &data << endl;

cout << value << &value << endl;

}

Output:

100 FFF4

56.47 FFF0

7

56.47

100

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

value

data

ALGORITHMS AND DATA STRUCTURES

Pointer VariablesThe pointer data type◦ Each address has a type, which depends on the (type of

the) variable it belongs to.

◦ Suppose we have declare the variableint v;

◦ Then the type of v‘s address isint *

pronounced as “pointer-to-int” or “integer pointer”

◦ We can also declare variables that have addresses as values. For example, a variable p holding an integer pointer is declared as

int *p;

8ALGORITHMS AND DATA STRUCTURES

Declaration of Pointer VariablesA pointer variable is declared by:

dataType *pointerVarName;

◦ The pointer variable pointerVarName is used to point to a variable with a value of type dataType

◦ The * before the pointerVarName indicates that this is a pointer variable, not a regular variable

◦ The * is not a part of the pointer variable name

9ALGORITHMS AND DATA STRUCTURES

Declaration of Pointer Variables (Cont ..)

Exampleint *ptr1;

float *ptr2;

◦ ptr1 is a pointer to an int variable i.e., it can have the address of the memory location allocated to an int value

◦ ptr2 is a pointer to a float variable i.e., it can have the address of the memory location allocated to a float value

10ALGORITHMS AND DATA STRUCTURES

Declaration of Pointer Variables (Cont ..)Whitespace doesn’t matter and each of the following will declare ptras a pointer (to a float) variable and data as a float variable

float *ptr, data;

float* ptr, data;

float (*ptr), data;

float data, *ptr;

11ALGORITHMS AND DATA STRUCTURES

Assignment of Pointer Variables

A pointer variable has to be assigned a valid memory address (initialized) before it can be used in the program

Example:float data = 50.8;float *ptr;ptr = &data;

This will assign the address of the memory location allocated for the floating point variable data to the pointer variable ptr. This is OK, since the variable data has already been allocated some memory space having a valid address

12ALGORITHMS AND DATA STRUCTURES

Assignment of Pointer Variables (Cont ..)

13

float data = 50.8;

float *ptr;

ptr = &data; 50.8

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

data

ALGORITHMS AND DATA STRUCTURES

Assignment of Pointer Variables (Cont ..)

14

float data = 50.8;

float *ptr;

ptr = &data; 50.8

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

ptr

data

ALGORITHMS AND DATA STRUCTURES

Assignment of Pointer Variables (Cont ..)

15

float data = 50.8;

float *ptr;

ptr = &data;

FFF4

50.8

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

ptr

data

ALGORITHMS AND DATA STRUCTURES

Assignment of Pointer Variables (Cont ..)

Don’t try to assign a specific integer value to a pointer variable since it can be disastrous

float *ptr;

ptr = 120;

16

• You cannot assign the address of one type of variable to a pointer variable of another type even though they are both integrals

int data = 50;

float *ptr;

ptr = &data;

ALGORITHMS AND DATA STRUCTURES

Initializing pointersA pointer can be initialized during declaration by assigning it the address of an existing variable

float data = 50.8;float *ptr = &data;

If a pointer is not initialized during declaration, it is wise to give it a NULL (or nullptr in C+11) value

int *ip = 0;float *fp = nullptr;

17ALGORITHMS AND DATA STRUCTURES

The NULL pointerThe NULL pointer is a valid address for any (pointer) data type.

◦ But NULL is not memory address 0. It is used to indicate that the pointer does not refer to a variable.

It is an error to dereference a pointer whose value is NULL.◦ Such an error may cause your program to crash, or behave erratically.

◦ It is the programmer’s job to check for this.

18ALGORITHMS AND DATA STRUCTURES

DereferencingDereferencing – Using a pointer variable to access the value stored at the location pointed by the variable◦ Provide indirect access to values and also called indirection

Done by using the dereferencing operator * in front of a pointer variable◦ Unary operator

◦ Highest precedence

19ALGORITHMS AND DATA STRUCTURES

Dereferencing (Cont ..)Example:

float data = 50.8;

float *ptr;

ptr = &data;

cout << *ptr;

Once the pointer variable ptr has been declared, *ptr represents the object pointed to by ptr (or the value located at the address specified by ptr) and may be treated like any other variable of float type

20ALGORITHMS AND DATA STRUCTURES

Dereferencing (Cont ..)The dereferencing operator * can also be used in assignments.

*ptr = 200;

◦ Make sure that ptr has been properly initialized

21ALGORITHMS AND DATA STRUCTURES

Dereferencing Example

22

#include <iostream.h>

void main()

{

float data = 50.8;

float *ptr;

ptr = &data;

cout << ptr << *ptr << endl;

*ptr = 27.4;

cout << *ptr << endl;

cout << data << endl;

}

Output:

FFF4

50.8

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

ptr

data

ALGORITHMS AND DATA STRUCTURES

Dereferencing Example (Cont ..)

23

#include <iostream.h>

void main()

{

float data = 50.8;

float *ptr;

ptr = &data;

cout << ptr << *ptr << endl;

*ptr = 27.4;

cout << *ptr << endl;

cout << data << endl;

}utput:

FFF4 50.80

FFF4

50.8

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

ptr

data

ALGORITHMS AND DATA STRUCTURES

Dereferencing Example (Cont ..)

24

FFF4

27.4

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

ptr

data

#include <iostream.h>

void main()

{

float data = 50.8;

float *ptr;

ptr = &data;

cout << ptr << *ptr << endl;

*ptr = 27.4;

cout << *ptr << endl;

cout << data << endl;

}

Output:

ALGORITHMS AND DATA STRUCTURES

Dereferencing Example (Cont ..)

25

FFF4

27.4

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

ptr

data

#include <iostream.h>

void main()

{

float data = 50.8;

float *ptr;

ptr = &data;

cout << ptr << *ptr << endl;

*ptr = 27.4;

cout << *ptr << endl;

cout << data << endl;

}

Output:27.4

ALGORITHMS AND DATA STRUCTURES

Dereferencing Example (Cont ..)

26

FFF4

27.4

FFF1

FFF0

FFF2

FFF3

FFF4

FFF5

FFF6

ptr

data

#include <iostream.h>

void main()

{

float data = 50.8;

float *ptr;

ptr = &data;

cout << ptr << *ptr << endl;

*ptr = 27.4;

cout << *ptr << endl;

cout << data << endl;

}

Output:27.4

ALGORITHMS AND DATA STRUCTURES

Operations on Pointer VariablesAssignment – the value of one pointer variable can be assigned to another pointer variable of the same type

Relational operations - two pointer variables of the same type can be compared for equality, and so on

Some limited arithmetic operations integer values can be added to and subtracted from a

pointer variablevalue of one pointer variable can be subtracted from

another pointer variable

27ALGORITHMS AND DATA STRUCTURES

const Pointer VariablesTwo possibilities

1. the ‘variable’ itself is a constant◦ the pointer value cannot be changed;

int v = 42;int * const q = &v;

2. the object to which it refers is (treated as) a constant.int v = 42;const int *p = &v;

28ALGORITHMS AND DATA STRUCTURES

Pointers to arraysA pointer variable can be used to access the elements of an array of the same type.

int gradeList[8] = {92,85,75,88,79,54,34,96};int * myGrades = gradeList;cout << gradeList[1];cout << *myGrades;cout << *(myGrades + 2);cout << myGrades[3];

Initially myGrades refers to the first element of gradeList.Note that the array name gradeList acts like the pointer variable myGrades.

29ALGORITHMS AND DATA STRUCTURES

30

Dynamic Memory Allocation

ALGORITHMS AND DATA STRUCTURES

Types of Program Data

Static Data: Memory allocation exists throughout execution of program

Automatic Data: Automatically created at function entry, resides in activation frame of the function, and is destroyed when returning from function

Dynamic Data: Explicitly allocated and deallocated during program execution by C++ instructions written by programmer

31ALGORITHMS AND DATA STRUCTURES

Allocation of MemoryStatic Allocation: Allocation of memory space at compile time.

Dynamic Allocation: Allocation of memory space at run time.

32ALGORITHMS AND DATA STRUCTURES

Scope refers to the visibility of variables. In other words, which parts of your program can see or use it.◦ A local variable is limited in scope to all the code below the

declaration until the end of the enclosing block.

◦ function arguments are local

◦ for-loop: scope is heading + body

◦ global variables are not limited in scope. Their visibility is throughout the entire program after declaration

33

Scope (revisited)

ALGORITHMS AND DATA STRUCTURES

Dynamic memory allocation

Dynamic allocation is useful when◦ arrays need to be created whose size is not known until run time

◦ complex structures of unknown size and/or shape need to be constructed as the program runs

◦ objects need to be created and the constructor arguments are not known until run time

34ALGORITHMS AND DATA STRUCTURES

Dynamic memory allocation

Pointers need to be used for dynamic allocation of memory

Use the operator new to dynamically allocate space

Use the operator delete to later free this space

35ALGORITHMS AND DATA STRUCTURES

The new operatorIf memory is available, the new operator allocates memory space for the requested object/array, and returns a pointer to (address of) the memory allocated.

If sufficient memory is not available, the new operator returns NULL.

The dynamically allocated object/array exists until the delete operator destroys it.

36ALGORITHMS AND DATA STRUCTURES

The delete operatorThe delete operator deallocates the object or array currently pointed to by the pointer which was previously allocated at run-time by the newoperator.

◦ the freed memory space is returned to Heap

◦ the pointer is then considered unassigned

If the value of the pointer is NULL there is no effect.

37ALGORITHMS AND DATA STRUCTURES

Example

38

FDE1

FDE0

0EC7

FDE2

FDE3

0EC4

0EC5

0EC6

ptrint *ptr;

ptr = new int;

*ptr = 22;

cout << *ptr << endl;

delete ptr;

ptr = NULL;

ALGORITHMS AND DATA STRUCTURES

39

Example (Cont ..)

int *ptr;

ptr = new int;

*ptr = 22;

cout << *ptr << endl;

delete ptr;

ptr = NULL;

0EC4

FDE1

FDE0

0EC7

FDE2

FDE3

0EC4

0EC5

0EC6

ptr

ALGORITHMS AND DATA STRUCTURES

40

Example (Cont ..)

int *ptr;

ptr = new int;

*ptr = 22;

cout << *ptr << endl;

delete ptr;

ptr = NULL;

0EC4

22

FDE1

FDE0

0EC7

FDE2

FDE3

0EC4

0EC5

0EC6

ptr

ALGORITHMS AND DATA STRUCTURES

41

Example (Cont ..)

int *ptr;

ptr = new int;

*ptr = 22;

cout << *ptr << endl;

delete ptr;

ptr = NULL;

0EC4

22

FDE1

FDE0

0EC7

FDE2

FDE3

0EC4

0EC5

0EC6

ptr

Output:

22

ALGORITHMS AND DATA STRUCTURES

42

Example (Cont ..)

int *ptr;

ptr = new int;

*ptr = 22;

cout << *ptr << endl;

delete ptr;

ptr = NULL;

?

FDE1

FDE0

0EC7

FDE2

FDE3

0EC4

0EC5

0EC6

ptr

ALGORITHMS AND DATA STRUCTURES

43

Example (Cont ..)

int *ptr;

ptr = new int;

*ptr = 22;

cout << *ptr << endl;

delete ptr;

ptr = NULL;

0

FDE1

FDE0

0EC7

FDE2

FDE3

0EC4

0EC5

0EC6

ptr

ALGORITHMS AND DATA STRUCTURES

Dynamic allocation and deallocation of arraysUse the new[IntExp] to create an array of objects instead of a single instance.

On the delete statement use [] to indicate that an array of objects is to be deallocated.

44ALGORITHMS AND DATA STRUCTURES

Example of dynamic array allocation

45

int* grades = NULL;

int numberOfGrades;

cout << "Enter the number of grades: ";

cin >> numberOfGrades;

grades = new int[numberOfGrades];

for (int i = 0; i < numberOfGrades; i++)

cin >> grades[i];

for (int j = 0; j < numberOfGrades; j++)

cout << grades[j] << " ";

delete [] grades;

grades = NULL;

ALGORITHMS AND DATA STRUCTURES

Dynamic allocation of 2D arrays

A two dimensional array is really an array of arrays (rows).

To dynamically declare a two dimensional array of int type, you need to declare a pointer to a pointer as:

int **matrix;

46ALGORITHMS AND DATA STRUCTURES

Dynamic allocation of 2D arrays (Cont ..)

To allocate space for the 2D array with r rows and c columns: You first allocate the array of pointers which will point to the arrays (rows)

matrix = new int*[r];

This creates space for r addresses; each being a pointer to an int (array).

Then you need to allocate the space for the 1D arrays themselves, each with a size of c

for(i=0; i<r; i++)

matrix[i] = new int[c];

47ALGORITHMS AND DATA STRUCTURES

Dynamic allocation of 2D arrays (Cont ..)The elements of the array matrix now can be accessed by the matrix[i][j] notation

Keep in mind, the entire array is not in contiguous space (unlike a static 2D array)

The elements of each row are in contiguous space, but the rows themselves are not. matrix[i][j+1] is after matrix[i][j] in memory, but

matrix[i][0] may be before or after matrix[i+1][0] in memory

48ALGORITHMS AND DATA STRUCTURES

Example: Binomial Coefficientsbinomial coefficient:

1

1

1

k

n

k

n

k

n

Pascal’s Identity

1 0

n

nn

)!(!

!

n-kk

n

k

n

35

246

5040

)!4(!3

!7

3

7

ALGORITHMS AND DATA STRUCTURES

Binomial coefficients in C++

int choose (int n, int k) {

if (k == 0 || k == n) {

return 1;

} else {

return choose(n-1,k-1) + choose(n-1,k);

}

}Double recursion:

(very) inefficient!

ALGORITHMS AND DATA STRUCTURES

Efficient solution using arraysint **binomial;

void PascalsTriangle (int N) {

binomial = new int *[N+1];

for (int n = 0; n <= N; n++) {

binomial[n] = new int [n+1];

binomial[n][0] = 1;

binomial[n][n] = 1;

for (int k = 1; k < n; k++) {

binomial[n][k] = binomial[n-1][k-1] + binomial[n-1][k];

}

}

}

Dynamic

programming

ALGORITHMS AND DATA STRUCTURES

52

Passing pointers to a function

ALGORITHMS AND DATA STRUCTURES

Pointers as arguments to functions

Pointers can be passed to functions just like other types.

Just as with any other argument, verify that the number and type of arguments in function invocation match the prototype (and function header).

53ALGORITHMS AND DATA STRUCTURES

Example of pointer argumentsvoid Swap(int *p1, int *p2) {

int temp = *p1;*p1 = *p2;*p2 = temp;

}

void main () {int x, y;cin >> x >> y;cout << x << " " << y << endl;Swap(&x,&y); // passes addresses of x and y explicitlycout << x << " " << y << endl;

}

54ALGORITHMS AND DATA STRUCTURES

Example of reference arguments

void Swap(int &a, int &b) {int temp = a;a = b;b = temp;

}

void main () {int x, y;cin >> x >> y;cout << x << " " << y << endl;Swap(x,y); // passes addresses of x and y implicitlycout << x << " " << y << endl;

}

55

•References are like pointer constants with implicit (de)referencing.

ALGORITHMS AND DATA STRUCTURES

More example

56

void main () {int r, s = 5, t = 6;int *tp = &t;r = MyFunction(tp,s);r = MyFunction(&t,s);r = MyFunction(&s,*tp);

}

int MyFunction(int *p, int i) {*p = 3;i = 4;return i;

}

ALGORITHMS AND DATA STRUCTURES

57

Memory leaks andDangling Pointers

ALGORITHMS AND DATA STRUCTURES

Memory leaksWhen you dynamically create objects, you can access them through the pointer which is assigned by the new operator

Reassigning a pointer without deleting the memory it pointed to previously is called a memory leak

It results in loss of available memory space

58ALGORITHMS AND DATA STRUCTURES

Memory leak example

59

int *ptr1 = new int;

int *ptr2 = new int;

*ptr1 = 8;

*ptr2 = 5;

ptr1

8

5

ptr2

ptr1

8

5

ptr2

ptr2 = ptr1;

How to avoid?

ALGORITHMS AND DATA STRUCTURES

Inaccessible objectAn inaccessible object is an unnamed object that was created by operator new and which a programmer has left without a pointer to it.

It is a logical error and causes memory leaks.

60ALGORITHMS AND DATA STRUCTURES

Dangling PointersIs a pointer that points to memory allocations that have been deallocated◦ local objects whereof the scope has ended

◦ dynamically allocated objects that have been deleted explicitly

61ALGORITHMS AND DATA STRUCTURES

Dangling Pointer example

62ALGORITHMS AND DATA STRUCTURES

int *answer ( ) {

int result = 6*7;

return &result;

}

void main ( ) {

int *ptr = answer ( );

cout << " answer = " << *ptr;

}

63

Dangling Pointer example 2

int *ptr1 = new int;

int *ptr2;

*ptr1 = 8;

ptr2 = ptr1;

ptr1

8

ptr2

delete ptr1;ptr1

ptr2How to avoid?

ALGORITHMS AND DATA STRUCTURES

Pointers to objects

ALGORITHMS AND DATA STRUCTURES

Pointers to (composite) objects

Any type that can be used to declare a variable/object can also have a pointer type.

Consider the following class:

65

class Rational{

private:int numerator;int denominator;

public:Rational(int n, int d);void Display();

};

ALGORITHMS AND DATA STRUCTURES

Pointers to objects (Cont..)

66

Rational *rp = NULL;

Rational r(3,4);

rp = &r;

0FFF0

FFF1

FFF2

FFF3

FFF4

FFF5

FFF6

FFF7

FFF8

FFF9

FFFA

FFFB

FFFC

FFFD

rp

ALGORITHMS AND DATA STRUCTURES

Pointers to objects (Cont..)

67

Rational *rp = NULL;

Rational r(3,4);

rp = &r;

0FFF0

numerator = 3denominator = 4

FFF1

FFF2

FFF3

3FFF4

FFF5

FFF6

FFF7

4FFF8

FFF9

FFFA

FFFB

FFFC

FFFD

rp

r

ALGORITHMS AND DATA STRUCTURES

Pointers to objects (Cont..)

68

Rational *rp = NULL;

Rational r(3,4);

rp = &r;

FFF4FFF0

numerator = 3denominator = 4

FFF1

FFF2

FFF3

3FFF4

FFF5

FFF6

FFF7

4FFF8

FFF9

FFFA

FFFB

FFFC

FFFD

r

rp

ALGORITHMS AND DATA STRUCTURES

Pointers to objects (Cont..)

If rp is a pointer to an object, then two notations can be used to reference the instance/object rppoints to.

Using the de-referencing operator *(*rp).Display();

Using the member access operator ->rp -> Display();

69ALGORITHMS AND DATA STRUCTURES

Dynamic Allocation of a Class ObjectConsider the Rational class defined before

Rational *rp;int a, b;cin >> a >> b;rp = new Rational(a,b);rp -> Display(); // (*rp).Display(); delete rp;rp = NULL;

70ALGORITHMS AND DATA STRUCTURES

Next week: lists

Questions?

71ALGORITHMS AND DATA STRUCTURES