technical module : pointers

41
Technical Module : Pointers #1 2000/01 Scientific Computing in OO Course code 3C59 Technical Module : Pointers In this module we will cover Pointers to primitives and objects Argument passing using pointers Memory allocation using new Memory freeing using delete An important use of a destructor You will probably be confused by the end of this. Particularly on the relation between pointers and references

Upload: kevina

Post on 08-Jan-2016

29 views

Category:

Documents


3 download

DESCRIPTION

Technical Module : Pointers. In this module we will cover. Pointers to primitives and objects Argument passing using pointers Memory allocation using new Memory freeing using delete An important use of a destructor. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Technical Module :  Pointers

Technical Module : Pointers #1

2000/01Scientific Computing in OO Course code 3C59

Technical Module : Pointers

In this module we will cover

• Pointers to primitives and objects

• Argument passing using pointers

• Memory allocation using new

• Memory freeing using delete

• An important use of a destructor

You will probably be confused by the end of this. Particularly on the relation between pointers and

references

Page 2: Technical Module :  Pointers

Technical Module : Pointers #2

2000/01Scientific Computing in OO Course code 3C59

Aims of this module

In this module we teach you about the use of pointers.

It will at first seem that pointers are the same as references, just more obtuse to use. In many cases this is true, but there are situations where you need to use

pointers.

In this module we first explain pointers and then show them in use for dynamic memory allocation.

Page 3: Technical Module :  Pointers

Technical Module : Pointers #3

2000/01Scientific Computing in OO Course code 3C59

1 Pointers

Pointers were invented as part of C long before references were ever invented in C++

Pointers, as the name suggests, allow you to indirectly refer to a primitive or object.

References are in many cases a simpler and more obvious way to indirectly refer to

a primitive or object. Therefore in many situations you no longer need pointers where they would have been used in C.

However pointers pervade C++ programs, so we must learn about them.

[ You might like to note that pointers have been abolished in Java. Only "references" exist, but confusingly they are similar to but not the same

as references in C++. ]

Page 4: Technical Module :  Pointers

Technical Module : Pointers #4

2000/01Scientific Computing in OO Course code 3C59

In its simplest form a pointer is declared and used like this

// Declare a pointer

int* ptrToInt ;

// Use a pointer

*ptrToInt = 3 ;

ptrToInt is NOT an integer

It is a thing which can POINT to an integer

ptrToInt is "dereferenced" using the * operator.

This line says:"set the thing which ptrToInt

points to to be 3"

Page 5: Technical Module :  Pointers

Technical Module : Pointers #5

2000/01Scientific Computing in OO Course code 3C59

Now we get confusing: here is how you set a pointer to point to an existing variable:

// Declare a pointer

int count = 5 ;

int* ptrToInt ;

// Set pointer to point to count

ptrToInt &count ;

This line says:"set ptrToInt points to be the

address of count"

It is the & operator which "takes the address of" count

Annoyingly and very confusingly, this use of & has absolutely nothing to do with the use of & in the context of references !

You WILL BE confused !

Page 6: Technical Module :  Pointers

Technical Module : Pointers #6

2000/01Scientific Computing in OO Course code 3C59

Pictorial examples:

Pointer to an integer:

*&$$%^%$£$^^int a ;

a is an integer - space has been allocated and probably contains garbage

It works the other way around, i.e.int b ;b = *pa ;

int* pa ;

pa is a pointer to an integer, but doesn’t point to anything sensible yet

*&$$%^%$£$^^

pa = &a ;

pa now points to a, remember & means “take address of”.

10

*pa = 10 ;

This places value 10 in the thing pointed to

Page 7: Technical Module :  Pointers

Technical Module : Pointers #7

2000/01Scientific Computing in OO Course code 3C59

2 Pointers to objects

In the same way (with one minor additional complication) one may use pointers to objects like this:

// Make a Thing object

Thing wombat ;

// Make a pointer to a Thing

Thing* ptrToAThing ;

// Now set the pointer to point at wombat

ptrToAthing = &wombat ;

Wombat

Page 8: Technical Module :  Pointers

Technical Module : Pointers #8

2000/01Scientific Computing in OO Course code 3C59

The minor complication is that when you have a pointer to an object you normally use the -> operator to invoke its methods

Instead of this (which works fine)

// make a pointer to a thingThing* ptrToAThing ;

//.... set it to point at some sensible Thing object...

// Now use the printContents method in an "obvious" fashion

(*ptrToAthing).printContents()

you normally do this:

// make a pointer to a thingThing* ptrToAThing ;

//.... set it to point at some sensible Thing object...

// Now use the printContents method using -> operator

ptrToAthing->printContents()

Page 9: Technical Module :  Pointers

Technical Module : Pointers #9

2000/01Scientific Computing in OO Course code 3C59

At this points students normally ask why ? what is the point of pointers ?what do they do that references dont do ?

As we said earleir, in many cases the answer is nothing because pointers were invented in C before C++ references.

If we tried to cover every way of using pointers in abstact examples now it would undoubtedly confuse you more than the good it would do.

(you would be unique if this were not the case !)

We therefore cover only two very common uses now:

argument passingdynamic memory allocation

and defer any other use of pointers to well defined situations where they might arise, and where hopefuly the purpose of use wouldbe clear.

Page 10: Technical Module :  Pointers

Technical Module : Pointers #10

2000/01Scientific Computing in OO Course code 3C59

Before C++ references were invented, pointers HAD to be used in C to pass arguments which you wanted to change. You can still do this in C++ like this:

This passes the address of count into to doSomething

int count ;

doSomething( &count ) ;

count

This makes an areain memory labeledas count

doSomething then uses the pointer to work on the original

3 Using pointers to pass primitive arguments

Page 11: Technical Module :  Pointers

Technical Module : Pointers #11

2000/01Scientific Computing in OO Course code 3C59

Inside the function doSomething you have to make the arguments match this

void doSomething( int* pcount ){

// accessing the integer pointed // to by pcount

*pcount = *pcount + 1 ;

… rest of code}

This is how you tell the function that it is receiving a pointer to the argument, I.e. a “pointer to an integer”rather than “an integer itself”

This is how you access the thing pointed to

Page 12: Technical Module :  Pointers

Technical Module : Pointers #12

2000/01Scientific Computing in OO Course code 3C59

This is identical to passing primitives (it can be used instead of passing a reference, but there is generally no point in doing so)

This passes the address of t into to doSomething

Thing t ;

doSomething( &t ) ;

t

This makes an areain memory labeledas t

doSomething then uses the pointer to work on the original

4 Using pointers to pass objects

Page 13: Technical Module :  Pointers

Technical Module : Pointers #13

2000/01Scientific Computing in OO Course code 3C59

If you are passing a user defined data type you probably want to use its methods. You normally do that like this:

void doSomething( Thing* ptr ){

// accessing a method // through the pointer

ptr->initialise( 10.) ;

... rest of code}

// Declare user defined data type

Thing t ;

// Call a function to change it:

doSomething( & t ) ;

This is how you access methods of the thing pointed to.

Page 14: Technical Module :  Pointers

Technical Module : Pointers #14

2000/01Scientific Computing in OO Course code 3C59

So far the only way we have ever created instances of data types is by declaring them in a piece of code

An alternative in C++ to explicitly create things in a free area of memory using

new

5 Memory allocation using "new"

Page 15: Technical Module :  Pointers

Technical Module : Pointers #15

2000/01Scientific Computing in OO Course code 3C59

/* Example of use of new */

ThreeVector* vec ;

vec = new ThreeVector ;

vec is declared as a pointer to a ThreeVector (but at this stage it doesnt point to anything - it is un-initialised).

At this point an area of memory is carved off and protected. vec is then set to point to it

Memoryfor a

ThreeVector

Think of new as a function which returns a

pointer to a new instance of the data type specified after it

Page 16: Technical Module :  Pointers

Technical Module : Pointers #16

2000/01Scientific Computing in OO Course code 3C59

As an example of where you might use pointers with new, here is a a puzzle for the whiteboard

Which of the following works/doesn’t work ?Explain why ?

Page 17: Technical Module :  Pointers

Technical Module : Pointers #17

2000/01Scientific Computing in OO Course code 3C59

// Code Amain(){ ThreeVector vec ;

vec = gimmeAVector( ) ;

dump( vec ) ;}

// Code AThreeVector gimmeAVector(){ ThreeVector v ;

return v ;}

Page 18: Technical Module :  Pointers

Technical Module : Pointers #18

2000/01Scientific Computing in OO Course code 3C59

// Code Bmain(){ ThreeVector* pvec ;

pvec = gimmeAVector( ) ;

dump2( pvec ) ;}

// Code BThreeVector* gimmeAVector(){ ThreeVector* pv ;

return pv ;}

Page 19: Technical Module :  Pointers

Technical Module : Pointers #19

2000/01Scientific Computing in OO Course code 3C59

// Code Cmain(){ ThreeVector* pvec ;

pvec = gimmeAVector( ) ;

dump( pvec ) ;}

// Code CThreeVector* gimmeAVector(){ ThreeVector v ;

return &v ;}

Page 20: Technical Module :  Pointers

Technical Module : Pointers #20

2000/01Scientific Computing in OO Course code 3C59

// Code Dmain(){ ThreeVector* pvec ;

pvec = gimmeAVector( ) ;

dump( pvec ) ;}

// Code DThreeVector* gimmeAVector(){ ThreeVector* pv ;

pv = new ThreeVector ;

return pv ;}

Page 21: Technical Module :  Pointers

Technical Module : Pointers #21

2000/01Scientific Computing in OO Course code 3C59

// Code DThreeVector* gimmeAVector(){ ThreeVector* pv ;

pv = new ThreeVector ;

return pv ;}

Very typically pointers are used like this, i.e.

-when you want to create something long lived inside a function

- when you want to return this thing to the caller without it going out of scope when you terminate

Page 22: Technical Module :  Pointers

Technical Module : Pointers #22

2000/01Scientific Computing in OO Course code 3C59

// Example of use of new and delete// in a function

void myFunction {

ThreeVector* pvec ;

pvec = new ThreeVector ;

.... ....

delete pvec ;

return;}

Very important !

When you have finished with memory you must delete it in order to give the memory back to the system

Memoryfor a

ThreeVector

6 Memory de-allocation using "delete"

Page 23: Technical Module :  Pointers

Technical Module : Pointers #23

2000/01Scientific Computing in OO Course code 3C59

// Example of use of new and delete// in a function

void myFunction {

ThreeVector* pvec ;

pvec = new ThreeVector ;

.... ....

// forgot to delete( pvec ) ;

return;}

If you fail to do this you will cause a

"memory leak"

The computer memory gets filled up with orphaned memory, and eventually falls over.

Memoryfor a

ThreeVector

Page 24: Technical Module :  Pointers

Technical Module : Pointers #24

2000/01Scientific Computing in OO Course code 3C59

The function returns, and the pointer goes out of scope.

But the memory remains allocated with nothing pointing to it !

Memoryfor a

ThreeVector

Page 25: Technical Module :  Pointers

Technical Module : Pointers #25

2000/01Scientific Computing in OO Course code 3C59

The most common situation where a memory leak occurs arises when you allocate some memory using new within an

object, then forget to delete it before the the object gets destroyed

7 An important use of the destructor

Page 26: Technical Module :  Pointers

Technical Module : Pointers #26

2000/01Scientific Computing in OO Course code 3C59

Here is an example of the sort of problem which can arise.

// The .h file for a badly written class

class BadClass { private: Thing* ptr ;

public: BadClass( ) ;

}

// The .cc file with constructor

BadClass::BadClass( ) { ptr = new Thing ;}

Page 27: Technical Module :  Pointers

Technical Module : Pointers #27

2000/01Scientific Computing in OO Course code 3C59

When you makea BadClass, then

(i) memory for a BadClass is allocated

(ii) the BadClass constructor is called which uses new to

allocate memory for a Thing, and sets the pointer to it

// some piece of code which makes a// BadClass instance

void mycode() {

BadClass b ;

... use it...

return ;} BadClass

Page 28: Technical Module :  Pointers

Technical Module : Pointers #28

2000/01Scientific Computing in OO Course code 3C59

When you makea BadClass, then

(i) memory for a BadClass is allocated

(ii) the BadClass constructor is called which uses new to

allocate memory for a Thing, and sets the pointer to it

Thing

// some piece of code which makes a// BadClass instance

void mycode() {

BadClass b ;

... use it...

return ;} BadClass

Page 29: Technical Module :  Pointers

Technical Module : Pointers #29

2000/01Scientific Computing in OO Course code 3C59

Thing

// some piece of code which makes a// BadClass instance

void mycode() {

BadClass b ;

... use it...

return ;} BadClass

When a BadClass object goes out of scope, then it gets destroyed, but this only deletes the

BadClass itself

The Thing is left hanging around with nothing

pointing to it

This is a MEMORY LEAK

Page 30: Technical Module :  Pointers

Technical Module : Pointers #30

2000/01Scientific Computing in OO Course code 3C59

Thing

// some piece of code which makes a// BadClass instance

void mycode() {

BadClass b ;

... use it...

return ;}

When a BadClass object goes out of scope, then it gets destroyed, but this only deletes the

BadClass itself

The Thing is left hanging around with nothing

pointing to it

This is a MEMORY LEAK

Page 31: Technical Module :  Pointers

Technical Module : Pointers #31

2000/01Scientific Computing in OO Course code 3C59

You should instead supply a destructor

~BetterClass( )

This destructor gets called immediately

before a BetterClass object gets destroyed

// The .h file for// A beter written class

class BetterClass { private: Thing* ptr ;

public: BetterClass( ) ; ~BetterClass( ) ;

}

// In the .cc file

BetterClass::~BetterClass( ){ delete ptr ;}

It deletes the Thing explicitly before the BetterClass object

goes out of existence

Page 32: Technical Module :  Pointers

Technical Module : Pointers #32

2000/01Scientific Computing in OO Course code 3C59

When you makea BetterClass, then

(i) memory for a BetterClass is

allocated

(ii) the BetterClass constructor is called which uses new to

allocate memory for a Thing, and sets the pointer to it

// some piece of code which makes a// BetterClass instance

void mycode() {

BetterClass b;

... use it...

return ;}

BetterClass

Page 33: Technical Module :  Pointers

Technical Module : Pointers #33

2000/01Scientific Computing in OO Course code 3C59

When you makea BetterClass, then

(i) memory for a BetterClass is

allocated

(ii) the BetterClass constructor is called which uses new to

allocate memory for a Thing, and sets the pointer to it

Thing

// some piece of code which makes a// BetterClass instance

void mycode() {

BetterClass b;

... use it...

return ;}

BetterClass

Page 34: Technical Module :  Pointers

Technical Module : Pointers #34

2000/01Scientific Computing in OO Course code 3C59

Thing

// some piece of code which makes a// BadClass instance

void mycode() {

BetterClass b ;

... use it...

return ;}

BetterClass

When a BetterClass object goes out of

scope,

(i) the destructor is called first

(ii) then it gets destroyed

Page 35: Technical Module :  Pointers

Technical Module : Pointers #35

2000/01Scientific Computing in OO Course code 3C59

// some piece of code which makes a// BadClass instance

void mycode() {

BetterClass b ;

... use it...

return ;}

BetterClass

When a BetterClass object goes out of

scope,

(i) the destructor is called first

(ii) then it gets destroyed

Page 36: Technical Module :  Pointers

Technical Module : Pointers #36

2000/01Scientific Computing in OO Course code 3C59

// some piece of code which makes a// BadClass instance

void mycode() {

BetterClass b ;

... use it...

return ;}

When a BetterClass object goes out of

scope,

(i) the destructor is called first

(ii) then it gets destroyed

Page 37: Technical Module :  Pointers

Technical Module : Pointers #37

2000/01Scientific Computing in OO Course code 3C59

Be careful

You only need to do this if your class is the only thing which points to some memory from inside itself.

You don’t need to do this is you are simply storing a pointer to something passed into you from outside via a method. For in such a case the outside environment is by

definition keeping track of the memory in question.

We repeat from an earlier module:

•You rarely need a destructor - although it is considered good practice to always provide one even if it does

nothing.

•However always consider it if you have used the new(..) operator inside your class

Memory leaks are one pf the biggest problems of C++(JAVA for instance does not have this problem)

Page 38: Technical Module :  Pointers

Technical Module : Pointers #38

2000/01Scientific Computing in OO Course code 3C59

8 this->

C++ provides a special pointer

Sometimes an object has need to refer to itself. Examples are:

• to pass itself to a function it is calling• to pass a pointer to itself to a function• to return a copy of itself, or a pointer to itself.

C++ provides a special inbuilt pointer in every object:

this->

this-> is actually very simple once you have grasped it.

Page 39: Technical Module :  Pointers

Technical Module : Pointers #39

2000/01Scientific Computing in OO Course code 3C59

// To explicitly refer to yourself inside a method

ThreeVector::magnitude( ){ float magsq = this->x * this->x + this->y * this->y + this->z * this->z ;

return sqrt( magsq ) ;}

Look at these two bits of code:

// To explicitly refer to yourself inside a method

ThreeVector::magnitude( ){ float magsq = x * x + y * y + z * z ;

return sqrt( magsq ) ;}

These bits of

code are Identical

if you dont put the this-

> in then the compiler does it

for you !

Page 40: Technical Module :  Pointers

Technical Module : Pointers #40

2000/01Scientific Computing in OO Course code 3C59

Summary of Module : Pointers

In this module we have covered the following topics.

• Pointers to primitive in-build types

* to de-reference a pointer

& to take the address of

• Pointers to objects

The same as for in-built types

In addition the -> operator for invoking methods

Page 41: Technical Module :  Pointers

Technical Module : Pointers #41

2000/01Scientific Computing in OO Course code 3C59

• Use of Pointers to pass arguments

A (not recommended) alternatice to references

Historical as pointers existed before references

• Use of new and delete

Dynamic allocation of memory

Returns a pointer to the allocated memory

You are responsible for keeping hold of the pointer

you must delete the allocation when finished.

• Important use for destructors

Destructors should delete any memory which an object allocates

with new UNLESS responsibility for the pointer has been passed

to some other object.

• this->