chapter 11 mechanisms for developing flexible list representations pointers and dynamic memory

60
Chapter 11 Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Upload: oswin-shepherd

Post on 20-Jan-2018

214 views

Category:

Documents


0 download

DESCRIPTION

Usefulness Necessary for dynamic objects Objects whose memory is acquired during program execution as the result of a specific program request  Dynamic objects can survive the execution of the function in which they are acquired Dynamic objects enable variable-sized lists, for example, the vector class The acquired memories of most programs can not be determined in compiling phase of program, but at run time

TRANSCRIPT

Page 1: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Chapter 11Chapter 11

Mechanisms for developing flexible list representations

Pointers and dynamic memory

Page 2: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

L-values R-values pointer types null address dereference operator * indirect members selector -> address operator & pointer assignment indirect assignment pointers as parameters pointers to pointers constant pointers pointers to constants arrays and pointers

pointers to function dynamic objects free store operators new and delete exception handling dangling pointers memory leak destructors copy constructor member assignment this pointer qualifier const

Key Concepts:Key Concepts:

Page 3: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Usefulness

Necessary for dynamic objects Objects whose memory is acquired during

program execution as the result of a specific program request Dynamic objects can survive the

execution of the function in which they are acquired

Dynamic objects enable variable-sized lists, for example, the vector class

The acquired memories of most programs can not be determined in compiling phase of program, but at run time

Page 4: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Memory Memory and its addressaddress

Page 5: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Memory Memory and its address addressMain board

Graphics adapterSound blaster

Hard disk driver

Main memory

CPU

Page 6: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Memory Memory and its address address

System Bus

CPU Memory

Output

device

Input devic

e

Page 7: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Memory Memory and its address addressSystem bus transfers the data information, address information and control information Data bus transfers the data information Address bus transfers the address

information Control bus transfers the control information

32 bits address bus has an ability of addressing memory space of 4GB From 0x00000000 to 0xFFFFFFFF

Page 8: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Memory Memory and its address addressMain memory

0x00000001

0x00000000

0x00000002

0x00000003

0x7FFFFFFF

0xFFFFFFFD

0xFFFFFFFE0xFFFFFFFF

NULL address

...

......

Page 9: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

L-value and R-valueL-value expressions

Represent objects that can be evaluated and modified

R-value expressions Represent objects that can only be evaluated

Considerint a;vector<int> b(3);int c[3];a = 1; // a: lvaluec[0] = 2*a + b[0]; // c[0], a, b[0]: lvalues

Observation Not all lvalues are the names of objects

Page 10: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Pointer basics

Pointer Object whose value represents the location of

another object In C++ there are pointer types for each type of

object Pointers to int objects Pointers to char objects Pointers to RectangleShape objects

Even pointers to pointers Pointers to pointers to int objectsNormally a pointer is an unsigned integer, its size is

variable with the operation system and compiler A 32 bits pointer occupies itself 4 bytes of memory A 16 bits pointer occupies itself 2 bytes of memory

Page 11: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Examples of initialized pointersint i = 1;char c = 'y';int *ptr = &i; // ptr is a pointer to int ichar *t = &c; // t is a pointer to a char c

Examples of uninitialized pointersint *iPtr; // iPtr is a pointer to an intchar *s ; // s is a pointer to a charRational *rPtr; // rPtr is a pointer to a // Rational

Syntax

TypeName * PointerName = &ObjectName

Indicates pointer object

Indicates to take the address of the object

Page 12: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Indirection Operator *An asterisk has two uses with regard to pointers In a definition, it indicates that the object is a

pointerchar *s; // s is of type pointer to char

In expressions, when applied to a pointer it evaluates to the object to which the pointer pointsint i = 1;

int *ptr = &i; // ptr points to i

*ptr = 2;

cout << i << endl; // display a 2

Page 13: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Address Operator &In a definition, & is used to define a reference to an objectIn expressions, when applied to a object as unary operator, & evaluates the address of the object

int i = 1;int j = 2;int *ptr;

ptr = &i; // ptr points to location of i*ptr = 3; // contents of i are updatedptr = &j; // ptr points to location of j*ptr = 4; // contents of j are updated

cout << i << " " << j << endl;

Page 14: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Memory Depiction

0xF001

0xF0020xF003

0xF004

0xF000

0xF005

0xF006

0xF008

0xF0090xF00A

0xF00B

0xF007

0xF00C

0xF00D

c

char c = 'y';

int *ptr = &i;

ptr

char *t = &c;

t

’y’

*ptr = 2;

*t = ’W’; ’W’ ptr = (int*)&c;

t = (char*)&i;

0xF004

0xF000

0xF000

0xF004

i

int i = 1;

12

Page 15: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Null Address0 is a pointer constant that represents the empty or null address Its value indicates that pointer is not pointing to

a valid object Cannot dereference a pointer whose value is null

int *ptr = 0;

cout << *ptr << endl; // invalid, ptr // does not point to // a valid int

Page 16: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Big advisePointers are error prone and should be carefully Pointers are error prone and should be carefully manipulated. We always prefer to use reference manipulated. We always prefer to use reference object instead of pointer object when ever object instead of pointer object when ever possiblepossiblePointer should be always initialized at definition. Pointer should be always initialized at definition. If there is not a object to point to, initialize it If there is not a object to point to, initialize it with null pointer (set its value to 0)with null pointer (set its value to 0)First check the validity of a pointer before using First check the validity of a pointer before using itit

if( ptr != 0 ) cout << *ptr << endl;

Page 17: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

ConsiderRational r(4,3);

Rational *rPtr = &r;

To select a member of r using rPtr and member selection, operator precedence requires (*rPtr).Insert(cout);

This syntax is clumsy, so C++ provides the indirect member selector operator ->

rPtr->Insert(cout);

Member Indirection

Page 18: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Pointers as parametersvoid IndirectSwap(char *Ptr1, char *Ptr2) {

char c = *Ptr1;*Ptr1 = *Ptr2;*Ptr2 = c;

}

int main() {

char a = 'y';char b = 'n';IndirectSwap(&a, &b);cout << a << b << endl;return 0;

}

Page 19: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Pointers to pointersint i = 5;int *Ptr = &i;int **PtrPtr = 0;PtrPtr = &Ptr;

PtrPtr Ptr i

51001100210031004

1011101210131014

1101110211031104

cout << Ptr << endl;cout << PtrPtr << endl;

Cout << *Ptr << endl;cout << *PtrPtr << endl;cout << **PtrPtr << endl;

// 1001// 1011

// 5// 1001// 5

Page 20: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Constants and PointersA constant pointer is a pointer such that we cannot change the location to which the pointer pointschar c = 'c';const char d = 'd';char * const ptr1 = &c;ptr1 = &d; // illegal*ptr1 = ’e’; // legal

A pointer to a constant value is a pointer object such that the value at the location to which the pointer points is considered constantconst char *ptr2 = &d;*ptr2 = 'e'; // illegal: cannot change d // through indirection with ptr2Ptr2 = &c; // legal

Page 21: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Arrays and Pointers

In C++ the name of an array is consider to be a constant pointer and points to first element of the array

int A[5] = {10,20,30,40,50};

int B[10]={0};

Ptr11000100410081012101610201024102810321036104010441048105210561060

A[0]A[1]A[2]A[3]A[4]B[0]B[1]B[2]B[3]B[4]B[5]B[6]B[7]B[8]B[9]

Ptr2

Ptr3

Ptr4

10203040500000000000

int *Ptr1 = A; int *Ptr2 = B;int *Ptr3 = &B[0]; int *ptr4 = &B[5];

Page 22: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Arrays and PointersIncrement and decrement operator can be applied to any type of pointer object++Ptr1;cout<< ptr1 << endl; cout<< *ptr1 << endl;

--Ptr4;cout<< ptr4 << endl; cout<< *ptr4 << endl;

Ptr11000100410081012101610201024102810321036104010441048105210561060

A[0]A[1]A[2]A[3]A[4]B[0]B[1]B[2]B[3]B[4]B[5]B[6]B[7]B[8]B[9]

Ptr4

10203040500000000000100420103

60

Page 23: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Arrays and PointersPtr1

1000100410081012101610201024102810321036104010441048105210561060

A[0]A[1]A[2]A[3]A[4]B[0]B[1]B[2]B[3]B[4]B[5]B[6]B[7]B[8]B[9]

10203040500000000000

Ptr1 += 3;cout<< Ptr1 << endl; cout<< *Ptr1 << endl;

Ptr4 -= 4;cout<< Ptr4 << endl;

Ptr1 = Ptr4 + 3;cout<< Ptr4 << endl;

Ptr4 += 9;

int *Ptr = Ptr1 + Ptr2 // illegal

Offset operation for pointer object

Pointer object plus or minus a integer constant

Ptr4

//be dangerous!!!

Page 24: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Arrays and PointersPtr1

1000100410081012101610201024102810321036104010441048105210561060

A[0]A[1]A[2]A[3]A[4]B[0]B[1]B[2]B[3]B[4]B[5]B[6]B[7]B[8]B[9]

10203040500000000000

cout<< Ptr1 << endl;

cout<< Ptr1[0] << endl;

cout<< *Ptr1 << endl;

cout<< Ptr1[3] << endl;

cout<< *(Ptr1+3) << endl;

Subscribing a pointer object [ ] operator for pointer

Page 25: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Pointers to functionUsage: as function parameters

Some member functions of SimpleWindow

void SetTimerCallback(TimerTickCallbackFunction Callback);

The name of a function is just a pointer to the function

Definition of pointers to function

ReturnType ( *FuncPtrName ) ( ParameterList );

int (*TimerTickCallbackFunction)();int (*MouseClickCallback)(const Position &);

Page 26: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Dynamic objectswhose memory is acquired at run time

Page 27: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Local objects and parameters

Object memory is acquired automatically

Object memory is returned automatically when object goes out of scope

Dynamic objects

Object memory is acquired by program with an allocation request new operation

Dynamic objects can exist beyond the function in which they were allocated

Object memory is returned by a deallocation request delete operation

Deference with local object

Page 28: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Operation specifies The type and number of objects

If there is sufficient memory to satisfy the request A pointer to sufficient memory is returned by the

operation

If there is insufficient memory to satisfy the request An exception is generated

An exception is an error state/condition which if not handled (corrected) causes the program to terminate

General New Operation Behavior

Memory for dynamic objects Requested from the free store

Free store is memory controlled by operating system

Page 29: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

The Basic New Form

Syntax

Beware The newly acquired memory is uninitialized

unless there is a default TypeName constructor

Ptr = new TypeName ;

Where Ptr is a pointer of type TypeName

Page 30: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Examples

int *iptr = new int;Rational *rptr = new Rational;

--iptr

0/1rptr

Rational object with default initialization

Uninitialized int object

Page 31: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Another Basic New Form

Initialization The newly acquired memory is initialized

using a TypeName constructor ParameterList provides the parameters to the

constructor

Syntax

TypeName *Ptr = new TypeName(ParameterList);

Where Ptr is a pointer of type TypeName

Page 32: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Examples

int *iPtr = new int(10);Rational *rPtr = new Rational(1,2);

rPtr

10iPtr

1/2

Page 33: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

The Primary New Form

Syntax

Where Ptr is a pointer of type SomeType SizeExpression is the number of contiguous objects of

type TypeName to be constructed -- we are making a list

Note The newly acquired list is initialized if there is a default

TypeName constructor

Because of flexible pointer syntax Ptr can be considered to be an array

TypeName *Ptr = new TypeName[SizeExpression];

Page 34: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Examplesint *A = new int [3];Rational *R = new Rational[2];A[1] = 5;Rational r(2/3);R[0] = r;

—A

2/3R

5

0/1

Page 35: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Right Array For The Jobcout << "Enter list size: ";int n;cin >> n;int *A = new int[n];

GetList(A, n);SelectionSort(A, n);DisplayList(A, n);

Note:

Use of the container classes of the STL is preferred from a software engineering viewpoint. For example vector class

Page 36: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Delete OperatorsForms of request

// used if storage came from newdelete P;

// used if storage came from new[]delete [] P;

Storage pointed to by P is returned to free store, and any program can reuse it P is now undefined

Page 37: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Cleaning Up

int n;cout << "Enter list size: ";cin >> n;

int *A = new int[n];

GetList(A, n);SelectionSort(A, n);DisplayList(A, n);

delete [] A;

Page 38: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Dangling Pointer Pitfallint *A = new int[5];for (int i = 0; i < 5; ++i) A[i] = i;

int *B = A;A

B0 1 2 3 4

A

B

0?

Beware this memory do not belong to the program any more

delete [] A;A = 0;

if(B != 0) cout << B[0] << endl; //???

Page 39: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Memory Leak Pitfallint *A = new int [5];for (int i = 0; i < 5; ++i)

A[i] = i;

A 0 1 2 3 4

A 0 1 2 3 4

-- -- -- -- --

These memory cannot be accessed by any program

A = new int [5];

Page 40: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

A Simple Dynamic List Type

A good example of the usage of dynamic objects

What we want

An integer list data type IntList with the basic features of the vector data type from the Standard Template Library

Features and abilities

True object Can be passed by value and reference Can be assigned and copied

Inspect and mutate individual elements Inspect list size Resize list Insert and extract a list

Page 41: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Sample IntList UsageIntList A( 5, 1);IntList B(10, 2);IntList C( 5, 4);

for (int i = 0, i < A.size(); ++i) {

A[i] = C[i];}

cout << A << endl; // [ 4 4 4 4 4 ]

A = B;A[1] = 5;cout << A << endl; // [ 2 5 2 2 2 2 2 2 2 2 ]

Page 42: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

IntList Definitionclass IntList {public:

// constructors IntList(int n = 10, int val = 0); IntList(const int A[], int n); IntList(const IntList &A);

// destructor ~IntList();

// inspector for size of the list int size() const; // assignment operator IntList & operator=(const IntList &A);

Page 43: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

IntList Definition (continued)public:

// inspector for element of constant listconst int& operator[](int i) const;// inspector/mutator for element of// nonconstant listint& operator[](int i);// resize listvoid resize(int n = 0, int val = 0);// convenience for adding new last elementvoid push_back(int val);

private:// data membersint *Values; // pointer to elementsint NumberValues; // size of list

};

Page 44: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

IntList Definition (continued)

// IntList auxiliary operators -- nonmembers

ostream& operator<<(ostream &sout, const IntList &A);

istream& operator>>(istream &sin, IntList &A);

Page 45: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Default ConstructorIntList::IntList(int n, int val) { assert(n > 0);

NumberValues = n; Values = new int [n];

assert(Values);

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

Values[i] = val; }

}

Page 46: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Gang of Three RuleIf a class has a data member that points to dynamic memory then that class normally needs a class-defined Copy constructor

Constructor that builds an object out of an object of the same type

Member assignment operator Resets an object using another object of the

same type as a basis Destructor

Anti-constructor that typically uses delete the operator on the data members that point to dynamic memory

Page 47: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Why A Tailored Copy Constructor

Suppose we use the default copy constructorIntList A(3, 1);

IntList B(A);

B 3

1 1 1A 3

2And then A[2] = 2;

Then B[2] is changed! Not what a client would expect

Implication Must use tailored copy constructor

Page 48: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Why A Tailored Copy Constructor

An other case, suppose we use the default copy constructor

IntList A(3, 1); {

IntList B(A); B[1] = 5; ... }

A[2] = 2; //what happened ???

Implication Must use tailored copy constructor

B 3

1 1A 3

15? ? ?

Page 49: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Tailored Copy ConstructorIntList::IntList(const IntList &A) {

NumberValues = A.size();Values = new int [size()];assert(Values);

for (int i = 0; i < size(); ++i)Values[i] = A[i];

}What kind of subscripting is being performed? A 3

1 111

B 31 111

Page 50: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Gang Of ThreeWhat happens when an IntList goes out of scope?

If there is nothing planned, then we would have a memory leak

Need to have the dynamic memory automatically deleted

Define a destructor A class object going out of scope automatically

has its destructor invoked

IntList::~IntList() { delete [] Values;}

Page 51: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

This PointerConsider

this

Inside a member function or member operator this is a pointer to the invoking object

IntList::size() { return NumberValues;}

or equivalently

IntList::size() { return this->NumberValues;}

Page 52: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

First Assignment Attempt

Algorithm

Return existing dynamic memory to free store

Acquire sufficient new dynamic memory

Copy the size and the elements of the source object to the target element

Page 53: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Initial Implementation (Wrong)

IntList& operator=(const IntList &A) { NumberValues = A.size();

delete [] Values; Values = new int [NumberValues ]; assert(Values);

for (int i = 0; i < A.size(); ++i) Values[i] = A[i];

return A;}

Consider what happens with the code segmentIntList C(5,1);C = C;

Page 54: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Member Assignment OperatorIntList& IntList::operator=(const IntList &A) {

if (this != &A) {

delete [] Values;

NumberValues = A.size();Values = new int [A.size()];assert(Values);

for (int i = 0; i < A.size(); ++i) { Values[i] = A[i];}

}

return *this;}

Page 55: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Accessing List Elements

// Compute an rvalue (access constant element)const int& IntList::operator[](int i) const { assert((i >= 0) && (i < size())); return Values[i];

}

// Compute an lvalueint& IntList::operator[](int i) { assert((i >= 0) && (i < size())); return Values[i];

}

Page 56: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Stream OperatorsShould they be members?

class IntList {// ...ostream& operator<<(ostream &sout);// ...

};

Answer is based on the form we want the operation to take

IntList A(5,1);A << cout; // member form (unnatural)cout << A; // nonmember form (natural)

Page 57: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Beware of FriendsIf a class needs to

Can provide complete access rights to a nonmember function, operator, or even another class Called a friend

Declaration example

class IntList {friend ostream& operator<< (

ostream &sout, const IntList &A);friend istream& operator>> (

ostream &sin, const IntList &A);

// ...

};

Page 58: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Implementing Friend <<ostream& operator<<(ostream &sout, const IntList &A){ sout << "[ "; for (int i = 0; i < A.NumberValues; ++i)

{ sout << A.Values[i] << " ";

} sout << "]";

return sout;}

Why client can directly access the private data member of A ?

Is it a good program ???

Page 59: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

Proper << Implementationostream& operator<<(ostream &sout, const IntList &A){ sout << "[ "; for (int i = 0; i < A.size(); ++i)

{ sout << A[i] << " ";

} sout << "]";

return sout;}

Page 60: Chapter 11 Mechanisms for developing flexible list representations Pointers and dynamic memory

End of Chapter End of Chapter 1111

Exercises 11.47, 11.49 and 11.50 as in oneExercises 11.55

Home worksHome works