cs103l spring 2018 unit 6: pointersbytes.usc.edu/files/cs103/slides/unit6.pdf · text pointer...

69
UNIT 6: POINTERS CS103L SPRING 2018

Upload: trinhnhan

Post on 27-Apr-2019

214 views

Category:

Documents


0 download

TRANSCRIPT

UNIT 6: POINTERSCS103L SPRING 2018

TEXT

POINTER MOTIVATION

▸ Scenario:

▸ Collaborating on a writing project. Lots of images. Document ends up being quite large.

▸ How to share the document?

▸ E-mail around a copy of the Word document as an attachment

▸ Upload to Google docs and e-mail URL

TEXT

POINTER MOTIVATION

▸ These two methods are quite different!

▸ Google Doc: much less info to send: URL = ~hundred characters, doc = 100MB

▸ Google Doc: everyone has access to the same document for collaboration

▸ E-mail: each person has own copy, can edit freely and privately

▸ We will see this analogy holds well for pointers.

▸ URL -> pointer to document

TEXT

POINTER PREVIEW

▸ Pointers in C++ will let us do the following (details later, of course!)

▸ Change the value of a variable declared in one function with a 2nd function

▸ Pass large data structures around a program without making copies

▸ Making copies is not free!

▸ Utilize dynamic memory

▸ allocate and de-allocate memory as program runs

▸ Interact with hardware based I/O (embedded systems)

TEXT

ANOTHER POINTER ANALOGY

▸ Safe Deposit Boxes

30

PointerstoPointersAnalogy• Wecanactuallyhavemultiplelevelsof

indirection(de-referencing)• UsingC/C++pointerterminology:

– *9=goldinbox7 (9=>7)– **16=goldinbox3 (16=>5=>3)– ***0=goldinbox3 (0=>8=>5=>3)

0 1 2 3 4 5

12 13 14 15 16 17

6 7 8 9 10 118 15 3

711

1 5 3

35

TEXT

POINTER BASICS

▸ So what is a pointer?

▸ Remember:

▸ In C++ variables live in memory

▸ Each memory location has an address

▸ Address is just another way of referring to the location *where* a variable is stored

TEXT

POINTER BASICS

▸ Pointers are VARIABLES

▸ Just like any other variable, has a value and is stored at a location

▸ Pointers simply store the address of *another* variable

▸ Value of a pointer is the memory location of another variable

▸ Other variable can be any C++ type: int, double, char… or even another pointer

▸ Also called references, because they can be used to “refer” to other variables

TEXT

REFERENCES

▸ The idea of a reference is very common

▸ URL is a reference to a website

▸ Phone number is a reference to your phone or VM box

▸ Excel sheets: =A1 is a reference in one cell that brings in data from another cell

TEXT

DECLARING POINTERS

▸ Just like other variable types, we can declare pointer variables

▸ This gives us a place to *store* the address of something

▸ Pointers are typed too! Need to know what type the point to.

▸ int* ptr; (create a pointer to an int)

▸ char* chr_ptr; (create a pointer to a char)

▸ double* d; (create a pointer to a double)

TEXT

POINTER SIZE

▸ Like all variables, pointers have a size, or number of bits

▸ 32-bits on some platforms

▸ 64-bits on more modern platforms: Intel, AMD, ARM

TEXT

POINTER OPERATORS

▸ In C++ we have two operators that let us work with pointers:

▸ & operator

▸ * operator

TEXT

& OPERATOR

▸ & operator is the “address-of” operator

▸ Returns the address of the variable it touches: &<variable name>

▸ &x, &y, &start_val, &index, &score

▸ Returns a pointer!

▸ An address is a pointer.

▸ Now we can fill our pointer variables:

▸ int x = 10;

▸ int* x_ptr = &x

TEXT

* OPERATOR

▸ * operator: pointer dereferencing operator

▸ Gives us the data (resolves the reference, aka de-references) at an address (so from a pointer)

▸ int x = 10;

▸ int* ptr = &x;

▸ cout << *ptr << endl;

▸ What does this print?

TEXT

& AND * OPERATORS

▸ & and * are inverses of each other:

▸ &value => address

▸ *address => value

▸ *(&value) => value

TEXT

& AND * HINTS

▸ Use & when you need to turn a variable into a pointer to that variable

▸ Use * when you need to get the value that lives at the address contained in a pointer

▸ Remember: a pointer is a variable, just a special kind that holds the address of another variable

TEXT

POINTERS AND ARRAYS

▸ Remember the mantra:

▸ int dat[10];

▸ What does the variable name ‘dat’ by itself resolve to?

▸ The starting address of dat! a.k.a a pointer to dat[0]

▸ or sometimes we say “the starting address of the dat array”

▸ Both show us ‘dat’ is just a pointer to the array

TEXT

LOOKING AT SOME POINTERS

▸ &x = ??

▸ &y = ??

▸ &z = ??

▸ &dat[1] = ??

▸ dat = ??

9

Pointers• ‘&’operatoryieldsaddressofavariableinC

(Tip:Read‘&foo’as‘addressoffoo’)– int x=30;chary=‘a’;

floatz=5.375;int dat[2]={107,43};

– &x =>??,– &y =>??,– &z =>??,– &dat[1] =??;– dat =>??

Memory

20bc420bc820bcc20bd020bd4

20bc0 0030‘a’5.37510743

0000

20bd820bdc

0020be0…

x

dat[1]

yz

dat[0]

int x = 30;

char y=‘a’;

float z= 5.375

int dat[2] = {107, 43};

TEXT

LOOKING AT SOME POINTERS

▸ &x = 0x20bc4

▸ &y = 0x20bc8

▸ &z = 0x20bcc

▸ &dat[1] = 0x20bd4

▸ dat = 0x20bd0

9

Pointers• ‘&’operatoryieldsaddressofavariableinC

(Tip:Read‘&foo’as‘addressoffoo’)– int x=30;chary=‘a’;

floatz=5.375;int dat[2]={107,43};

– &x =>??,– &y =>??,– &z =>??,– &dat[1] =??;– dat =>??

Memory

20bc420bc820bcc20bd020bd4

20bc0 0030‘a’5.37510743

0000

20bd820bdc

0020be0…

x

dat[1]

yz

dat[0]

int x = 30;

char y=‘a’;

float z= 5.375

int dat[2] = {107, 43};

TEXT

DECLARING POINTERS

▸ Just like we declare a variable to hold and int, or double we declare a pointer to hold the address of some other variable

▸ Use the * when declaring to modify the type

11

Pointers

• Justaswedeclarevariablestostoreint’s anddouble’s,

wecandeclareapointervariable tostorethe“address-of”(or“pointer-to”)anothervariable

– Requires4-bytesofstorageina32-bitsystemor

8-bytesina64-bitsystems

– Usea‘*’afterthetypetoindicatethisapointervariable

tothattypeofdata

• Whydidpeoplechoose'*'todeclareapointervariable?

• Becauseyou'dhavetoputa'*'infrontofthevariableto

getanactualdataitem(i.e.togettheint thatanint pointerpoints

to,puta'*'infrontofthepointervariable.

• Declarevariables:– int x = 30; char y='a';

float z = 5.375;int dat[2] = {107,43};

– int *ptr1; ptr1 = &x; // ptr1 = 0x20bc4ptr1 = &dat[0]; // Change ptr1 = 0x20bd0 //(i.e.you can change what a pointer points to)

– float *ptr2 = &z; // ptr2 = 0x20bcc

Memory

20bc420bc820bcc20bd020bd4

20bc0 0030‘a’5.37510743

20bd820bdc

0020be0…

x

dat[1]

yz

dat[0]

ptr1ptr2

int x = 30; char y=‘a’; float z= 5.375 int dat[2] = {107, 43};

int *ptr1; ptr1 = &x; //ptr1 = 0x20bc4 ptr1 = &dat[0]; // ptr1 is now 0x20bd0 //note: this shows you can change the value of a pointer float* ptr2 = &z;

0x20bc40x20bd00x20bcc

TEXT

DE-REFERENCING

▸ Once a pointer points somewhere, we need a way to get the *value* at the destination

▸ Use the * operator (dereference)

▸ *var = “value pointed to by var” or “value at address given by var”

13

De-referencing/Indirection

• Onceapointerhasbeenwrittenwithanaddressofsome

otherobject,wecanuseittoaccessthatobject(i.e.

dereferencethepointer)usingthe‘*’ operator

• Read‘*foo’as…

– ‘valuepointedtobyfoo’

– ‘valueattheaddressgivenbyfoo’

(not‘valueoffoo’or‘valueofaddressoffoo’)

• UsingURLanalogy,usingthe*operatoronapointeris

like“clickingonaURL”(followthelink)

• Examples:

– ptr1=dat;

int a=*ptr1+5;

– (*ptr1)++;//*ptr =*ptr +1;

– *ptr2 =*ptr1 - *ptr2;

Memory

20bc420bc820bcc20bd020bd4

20bc0 0030‘a’5.37510743

20bd020bcc

20bd820bdc

0020be0…

x

dat[1]

yz

dat[0]

ptr1ptr2a

ptr1 = dat; int a = *ptr1 + 5; (*ptr1)++; // *ptr1 = *ptr1 + 1; *ptr2 = *ptr1 - *ptr2;

a = 112dat[0] = 108

z = 108 - 5.375 = 102.625

TEXT

SYNTAX CHECK

15

CuttingthroughtheSyntax• ‘*’inatypedeclaration=declare/allocateapointer• ‘*’inanexpression/assignment=dereference

Declaringapointer De-referencingapointer

char *p*p+1int *ptr*ptr =5*ptr++char *p1[10];

YesYes

YesYesYes

Yes

Helpful tip to understand syntax: We declare an int pointer as:• int *p because when we dereference it as *p we get an int• char *x is a declaration of a pointer and thus *x in code yields a char

TEXT

POINTER CHECK POINT

int x,y; int *p = &x; int *q = &y; x = 35; y = 46; p = q; *p = 78; cout << x << “ “ << y << endl; cout << *p << “ “ << *q << endl;

TEXT

POINTER/ARRAY REVIEW

▸ Review:

▸ sizeof(int)?

▸ sizeof(double)?

▸ What does the name of an array evaluate to?

▸ If we declare int dat[4] and dat = 0x200, where is dat[1]? dat[2]?

TEXT

POINTER ARITHMETIC

▸ Pointers are *just* variables that happen to store the address of another variable, an address is just a number

▸ So we can imagine doing math with the numbers

▸ int dat[2]; int* ptr = dat;

▸ ptr++;

▸ If dat=0x200, which makes more sense:

▸ ptr is now 0x201

▸ ptr is now 0x204

TEXT

POINTER ARITHMETIC

▸ Pointer arithmetic shows duality between pointers and arrays

▸ Adding/subtracting to a pointer adjusts it by the size of the data type

▸ int* ptr = dat; ptr++ //increase ptr by 4

▸ char* ptr = name; ptr++ //increase ptr by 1

▸ double* ptr = data; ptr++ //increase ptr by 8

TEXT

POINTER ARITHMETIC

▸ Why do this strange (but helpful) math?

▸ What does the name of an array resolve to?

▸ The address of the first element = pointer to the first element

▸ C/C++ make no distinction between an array and a pointer

▸ Pointer arithmetic lets you iterate over or skip around an array with math:

▸ int dat[10]; int* ptr = dat;

▸ cout << dat[i];

▸ cout << *(ptr+i);

TEXT

POINTER ARITHMETIC EXAMPLE

19

PointerArithmetic• Pointersarevariablesstoringaddressesand

addressesarejustnumbers• Wecanperformadditionorsubtractiononthose

pointervariables(i.e.addresses)justlikeanyothervariable

• Thenumberadded/subtractedisimplicitlymultipliedbythesizeoftheobjectsothepointerwillpointtoavaliddataitem– int *ptr =dat;ptr =ptr +1;– //addressinptr wasincrementedby4

• Examples:– ptr1=dat;– x=x+*ptr1;//x=137– ptr1++;//ptr1nowpointsatdat[1]– x=x+*ptr1++;//x=dat[1]=137+43then

//inc.ptr1to0x20bd8– ptr1=ptr1-2;//ptr1nowpointsbackatdat[0]

Memory

20bc420bc820bcc20bd020bd4

20bc0 0030‘a’5.37510743

20bd020bcc

20bd820bdc

0020be0…

x

dat[1]

yz

dat[0]

ptr1ptr2

ptr1 = dat; //point ptr1 at dat[0]

x = x + *ptr1; //x = 137

ptr1++; //ptr1 now points to dat[1]

x = x + *ptr1; //x = 137 + 43

ptr1 -= 1; //ptr1 now points back to dat[0]

TEXT

POINTERS AND ARRAY INDEXING

▸ C/C++ make no distinction between pointer arithmetic and array indexing

▸ They are equivalent!

▸ Array syntax: data[i]

▸ get the item at the i-th index from the start of the data array)

▸ Pointer syntax *(data + i)

▸ Add i*sizeof() to the data pointer and dereference to get value

▸ There are exactly the same operation!

TEXT

MORE POINTER/ARRAY EXAMPLES

int data[10]; //data lands at memory address 520

*(data+4) = 50; //data[4] = 50;

int* ptr = data; //now ptr can be used to access data array

ptr[1] = ptr[2] + ptr[3]; //same as data[1] = data[2]+data[3]

20

PointerArithmeticandArrayIndexing• Arrayindexingandpointerarithmeticareverymuchrelated

• Arraysyntax:data[i]– Saysgetthei-th valuefromthestartofthedataarray

• Pointersyntax:*(data+i)– Saysthesamethingasdata[i]

• Wecanusepointersandarraynamesinterchangeably:– int data[10];//data=520;

– *(data+4)=50;//data[4]=50;

– int*ptr =data;//ptr nowpointsat520too

– ptr[1]=ptr[2]+ptr[3];//sameasdata[1]=data[2]+data[3]

Memory

520

09 08 07 06 50 04524 528 532 536 540

data = 520

int data[10]

520ptr

TEXT

ANOTHER POINTER/ARRAY EXAMPLE21

Arrays&Pointers• Haveauniquerelationship• Arraynameevaluatestostart

addressofarray– Thus,thenameofaninteger

arrayhastype:int*– Thenameofcharacterarray/

textstringhastype:char*

• Arrayindexingissameaspointerarithmetic

int main(int argc, char *argv[]){int data[10] = {9,8,7,6,5,4,3,2,1,0};

int* ptr, *another; // * needed for each// ptr var. you // declare

ptr = data; // ptr = start address // of data

another = data; // another = start addr.

for(int i=0; i < 10; i++){data[i] = 99;ptr[i] = 99; // same as line above*another = 99; // same as line aboveanother++;

}

int x = data[5];x = *(ptr+5); // same as line abovereturn 0;

}

TEXT

SO WHY USE POINTERS?

▸ Reason #1 (from slide 4)

▸ “Change the value of a variable declared in one function with a 2nd function”

▸ Known as pass-by-reference

▸ We got a preview with passing arrays (which are just pointers!)

TEXT

PASS BY REFERENCE

▸ We know this doesn’t work

▸ Why?

▸ Pass-by-value

▸ A *copy* of the actual parameter is passed into the formal parameter

23

Code for all functions

PassbyValue• Noticethatactualargumentsaredifferent

memorylocations/variablesthantheformalarguments

• Whenargumentsarepassedacopy oftheactualargumentvalue(e.g.3)isplacedintheformalparameter(x)

• Thevalueofycannotbechangedbyanyotherfunction(rememberitislocal)

Data for main (a, y=3) and return link

Data for decrement_it(y=3 then 2) and return link

System stack area0xffff ffff

0x0000000

System Memory

(RAM)

Address Code for all functions

void decrement_it(int);

int main(){int a, y = 3;decrement_it(y);cout << “y = “ << y << endl;

}

void decrement_it(int y){

y--;}

Data for main (a, y=3) and return link

23

Code for all functions

PassbyValue• Noticethatactualargumentsaredifferent

memorylocations/variablesthantheformalarguments

• Whenargumentsarepassedacopy oftheactualargumentvalue(e.g.3)isplacedintheformalparameter(x)

• Thevalueofycannotbechangedbyanyotherfunction(rememberitislocal)

Data for main (a, y=3) and return link

Data for decrement_it(y=3 then 2) and return link

System stack area0xffff ffff

0x0000000

System Memory

(RAM)

Address Code for all functions

void decrement_it(int);

int main(){int a, y = 3;decrement_it(y);cout << “y = “ << y << endl;

}

void decrement_it(int y){

y--;}

Data for main (a, y=3) and return link

TEXT

PASS-BY-POINTER (OR PASS-BY-REFERENCE)

▸ Rewrite to use pointers. Now it works.

▸ Pointer value (memory address) is still passed-by-value

▸ But we can dereference the memory address to manipulate the value!

▸ The *value* of y in main() is changed and persists after decrement_it() runs

24

Code for all functions

PassbyReference• Pointervalue(i.e.theaddress)isstillpassed-by-

value(i.e.acopyismade)• However,thevalueofthepointerisareference

toy(i.e.y’s address)anditisreallythevalueofythatdoit()operateson

• Thuswesaywearepassing-by-reference• ThevalueofyisCHANGEDbydoit()andthat

changeisvisiblewhenwereturn.

Data for main (a=??, y=3, ptr=0x20bd4) and return link

System stack area0xffff ffff

0x0000000

System Memory

(RAM)

Address Code for all functions

int main(){int a, y = 3;// assume y @ 0x20bd4 // assume ptra = y;decrement_it(&y);cout << “a=“ << a;cout << “y=“ << y << endl;return 0;

}

// Remember * in a type/// declaration means “pointer” // variablevoid decrement_it(int* x){

*x = *x - 1;}

Data for main (a=3, y=3) and return link

Resulting Output:a=3, y=2

Data for doit(x=0x20bd4) and return link

Data for main (a=3, y=2) and return link

24

Code for all functions

PassbyReference• Pointervalue(i.e.theaddress)isstillpassed-by-

value(i.e.acopyismade)• However,thevalueofthepointerisareference

toy(i.e.y’s address)anditisreallythevalueofythatdoit()operateson

• Thuswesaywearepassing-by-reference• ThevalueofyisCHANGEDbydoit()andthat

changeisvisiblewhenwereturn.

Data for main (a=??, y=3, ptr=0x20bd4) and return link

System stack area0xffff ffff

0x0000000

System Memory

(RAM)

Address Code for all functions

int main(){int a, y = 3;// assume y @ 0x20bd4 // assume ptra = y;decrement_it(&y);cout << “a=“ << a;cout << “y=“ << y << endl;return 0;

}

// Remember * in a type/// declaration means “pointer” // variablevoid decrement_it(int* x){

*x = *x - 1;}

Data for main (a=3, y=3) and return link

Resulting Output:a=3, y=2

Data for doit(x=0x20bd4) and return link

Data for main (a=3, y=2) and return link

TEXT

HERE COMES SWAP AGAIN!

▸ Task: write function to swap the value of two variables.

▸ We know pass-by-value won’t work.

▸ Swap would be performed on variables *local* to the function

▸ With pointers, we can implement swap

▸ Memory address are passed in and dereferenced to perform swap

25

SwapTwoVariables• Classicexampleofissueswithlocal

variables:– Writeafunctiontoswaptwovariables

• Pass-by-valuedoesn’twork– Copyismadeofx,y frommainand

passedtox,y ofswapit…Swapisperformedonthecopies

• Pass-by-reference(pointers)doeswork– Addressesoftheactualx,y variablesin

mainarepassed– Usethoseaddresstochangethose

physicalmemorylocations

int main(){int x=5,y=7;swapit(x,y);cout << "x=" << x << " y=";cout << y << endl;

}

void swapit(int x, int y){ int temp;

temp = x;x = y;y = temp;

}

int main(){ int x=5,y=7;swapit(&x,&y);cout << “x=“ << x << “y=“;cout << y << endl;

}

void swapit(int *x, int *y){ int temp;

temp = *x;*x = *y;*y = temp;

}

program output: x=5,y=7

program output: x=7,y=5

TEXT

PASSING ARRAYS AS ARGUMENTS

▸ We’ve seen this in “arrays” lecture, now we understand even better

▸ Remember C/C++ doesn’t keep track of the size for us, so *most* functions that take arrays will also take a size parameter

26

PassingArraysasArguments• Infunctiondeclaration/prototypefor

theformal parameteruse– “type[]”or“type*”toindicateanarray

isbeingpassed• Whencallingthefunction,simply

providethenameofthearrayastheactual argument– InC/C++usinganarraynamewithout

anyindexevaluatestothestartingaddressofthearray

• CdoesNOTimplicitlykeeptrackofthesizeofthearray– Thuseitherneedtohavethefunction

onlyacceptarraysofacertainsize– Orneedtopassthesize(length)ofthe

arrayasanotherargument

void add_1_to_array_of_10(int []);void add_1_to_array(int *, int);int main(int argc, char *argv[]){int data[10] = {9,8,7,6,5,4,3,2,1,0};add_1_to_array_of_10(data);cout << “data[0]” << data[0] << endl;add_1_to_array(data,10);cout << “data[9]” << data[9] << endl;return 0;

}

void add_1_to_array_of_10(int my_array[]){int i=0;for(i=0; i < 10; i++){my_array[i]++;

}}

void add_1_to_array(int *my_array, int size){int i=0;for(i=0; i < size; i++){my_array[i]++;

}}Memory

520

09 08 07 06 05 04524 528 532 536 540

520

520

520

520

TEXT

ARGUMENT PASSING EXAMPLE

▸ Now we can write helpful functions that do useful things on arrays

27

Memory (RAM)

main:

(len = 0

data[0] = ?

data[1] = ?

data[2] = ?

)

ArgumentPassingExample

Code

Globals

0

Heap

fffffffc

Address#include <iostream>using namespace std;

int main(){int len=0;int data[100];

len = fill_data(data, 100);

for(int i=0; i < len; i++)cout << data[i] << “ “;

cout << endl;return 0;

}

// fills in integer array w/ int’s// from user until -1 is enteredint fill_data(int *array, int max){

int val = 0;int i = 0;while(i < max){cin >> val;if (val != -1)array[i++] = val;

else break;

}return i;

}

fill_data

(array=0xbf008,

max = 100

val=0, i = 0)

0xbf004

0xbf008

0xbf00c

Memory (RAM)

main:

(len = 2

data[0] = 4

data[1] = 3

data[2] = ?

)

Code

Globals

0

Heap

fffffffc

Address

fill_data

(array=0xbf008,

mas = 100

val = -1, i = 2)

0xbf004

0xbf008

0xbf00c

TEXT

IN CLASS EXCERCISES

▸ Swap

▸ Roll2

▸ Product

TEXT

POINTERS TO POINTERS

▸ Say what?

▸ As if pointers are not confusing enough!

▸ Extend our safe deposit box analogy

TEXT

POINTERS TO POINTERS ANALOGY

▸ A box might contain gold

▸ Or it contains a box-id (and presumably the key)

▸ You can follow the chain of box-ids until you find the gold

▸ No limit to the # of indirections

▸ *9 = gold in box 7 (9 -> 7)

▸ **16 = gold in box 3 (16 -> 5 -> 3)

▸ ***0 = gold in box 3 (0 -> 8 -> 5 -> 3)

30

PointerstoPointersAnalogy• Wecanactuallyhavemultiplelevelsof

indirection(de-referencing)• UsingC/C++pointerterminology:

– *9=goldinbox7 (9=>7)– **16=goldinbox3 (16=>5=>3)– ***0=goldinbox3 (0=>8=>5=>3)

0 1 2 3 4 5

12 13 14 15 16 17

6 7 8 9 10 118 15 3

711

1 5 3

35

TEXT

POINTERS TO POINTERS

▸ In C/C++ we can do the same thing.

▸ Remember, pointers are variables.

▸ They just happen to hold the memory address of another variable.

▸ Now they just happen to hold the memory address of another variable that also happens to hold the memory address of…(like inception)

TEXT

LEVELS OF INDIRECTION

▸ Since we can have as many levels of indirection as we want, we need to tell compiler how many there are when declaring the pointers:

int *p; //pointer to an int, one hop away

double **q; //pointer to a double, two hops away

TEXT

POINTERS TO POINTERS

▸ So now we can create pointers to pointers, what does that look like?

int k, x[3] = {5,7,9};

int *ptr1, **ptr2;

ptr1 = x;

ptr2 = &ptr1;

k = *ptr1;

k = (**ptr2) + 1;

k = *(*ptr2 + 1);

Declaration Expression Yields

int *ptr1 *ptr int

int **ptr2 **ptr2 int

*ptr2 int*

TEXT

POINTERS TO POINTERS

▸ Follow the chain…

33

PointerstoPointersto…

• Pointerscanpointtootherpointers– Essentiallyachainof“links”

• Example– int k,x[3]={5,7,9};– int *myptr,**ourptr;– myptr =x;– ourptr =&myptr;– k=*myptr;//k=5– k=(**ourptr)+1;//k=6– k=*(*ourptr +1);//k=7

Memory

20bc420bc820bcc20bd020bd4

20bc0 00579

20bc420bd0

0000

20bd820bdc

0020be0…

X[0]

ourptr

X[1]X[2]myptr

kint k, x[3] = {5,7,9};

int *ptr1, **ptr2;

ptr1 = x;

ptr2 = &ptr1;

k = *ptr1; //k = 5

k = (**ptr2) + 1; //k = 6

k = *(*ptr2 + 1); //k = 7

TEXT

POINTERS TO POINTER REVIEW

▸ Consider the declarations: int k, x[3] = {5,7,9};

int *ptr1, **ptr2;

Expression Typex[0] int

x int*ptr1 int**ptr1 int*ptr2 int*

ptr1+1 int*ptr2 int**

TEXT

C-STRING CONSTANTS

▸ Review: text in “double quotes” is a string constant

▸ The end up being an array of NULL terminated char’s (c-string)

▸ Assigned memory address

▸ If you check, the type is const char*

▸ You cannot/should not *change* these strings (hence the const)

37

C-StringConstants• C-Stringconstantsarethethings

wetypein"…" andarestoredsomewhereinmemory(chosenbythecompiler)

• WhenyoupassaC-stringconstanttoafunctionitpassesthestartaddressandit'stypeisknownasaconst char*– char*becauseyouarepassingthe

address– const becauseyoucannot/shouldnot

changethisarray'scontents

int main(int argc, char *argv[]){// These are examples of C-String constantscout << "Hello" << endl;cout << "Bye!" << endl;...

}

B y e ! \0

240 244H e l l \0o

300 305

#include <cstring>//cstring library includes//void strcpy (char * dest, const char* src);int main(int argc, char *argv[]){char name[40];strcpy(name, "Tommy");

}

name = 240 279T o m m \0y

300 305

300

300

240

TEXT

ARRAYS OF POINTERS AND C-STRINGS

▸ Sometimes need to store several arrays

▸ The arrays are related, like names

▸ C-strings are arrays of char variables

▸ Is this a good way to do it?

38

Arraysofpointers

• Weoftenwanttohaveseveralarraystostoredata– Storeseveraltextstrings

• Thosearraysmayberelated(i.e.allnamesofstudentsinaclass)

int main(int argc, char *argv[]){int i;char str1[] = “Bill”;char str2[] = “Suzy”;char str3[] = “Pedro”;char str4[] = “Ann”;

// I would like to print out each namecout << str1 << endl;cout << str2 << endl;...

}

Painful

B i l l \0str1=240 244

S u z y \0

P e d r \0o

A n n \0

str2=288 292

str3=300 305

str4=196 199

38

Arraysofpointers

• Weoftenwanttohaveseveralarraystostoredata– Storeseveraltextstrings

• Thosearraysmayberelated(i.e.allnamesofstudentsinaclass)

int main(int argc, char *argv[]){int i;char str1[] = “Bill”;char str2[] = “Suzy”;char str3[] = “Pedro”;char str4[] = “Ann”;

// I would like to print out each namecout << str1 << endl;cout << str2 << endl;...

}

Painful

B i l l \0str1=240 244

S u z y \0

P e d r \0o

A n n \0

str2=288 292

str3=300 305

str4=196 199

TEXT

ARRAYS OF POINTERS TO C-STRINGS

▸ Is this better?

▸ Somewhat?

▸ What does names resolve to?

▸ The address of the first char*

▸ names has what type? char**

▸ What type does names[0] have?

▸ char*

39

Arraysofpointers

• Weoftenwanttohaveseveralarraystostoredata– Storeseveraltextstrings

• Thosearraysmayberelated(i.e.allnamesofstudentsinaclass)

• Whattypeis'names'?– Theaddressofthe0-thchar*

inthearray– Theaddressofachar*is

reallyjustachar**

int main(int argc, char *argv[]){int i;char str1[] = “Bill”;char str2[] = “Suzy”;char str3[] = “Pedro”;char str4[] = “Ann”;char *names[4];

names[0] = str1; ...; names[3] = str4;for(i=0; i < 4; i++){cout << names[i] << endl;

} ...

}Still painful

B i l l \0240 244

S u z y \0

P e d r \0o

A n n \0

288 292

300 305

196 199

names = 520524528

532

names[0]names[1]names[2]

names[3]

240288300196

TEXT

ARRAYS OF POINTERS

▸ Remember a pointer is just another variable, so we can have arrays of pointers (just like we could have an array of ints)

40

Arraysofpointers

• Wecanhavearraysofpointersjustlikewehavearraysofotherdatatypes

• Usuallyeachvalueofthearrayisapointertoacollectionof“related”data– Couldbetoanotherarray

char *names[4] ={“Bill”,“Suzy”,“Pedro”,“Ann”};

int main(int argc, char *argv[]){int i;

for(i=0; i < 4; i++){cout << names[i] << endl;

}return 0;

}

B i l l \0240 244

S u z y \0

P e d r \0o

A n n \0

288 292

300 305

196 199

names = 520 240524528

532

288300196

names[0]names[1]names[2]

names[3]

Painless?!?

TEXT

NOW WE CAN UNDERSTAND COMMAND LINE ARGUMENTS

▸ When we run a command, the shell gives our program some information:

▸ int argc -> #of command line arguments

▸ char* argv[] -> array argc# of pointers to C-strings

▸ The command line is broken down by whitespace, each piece gets a C-string, and a spot in argv[]

▸ argv[0] is always program name

▸ Example:

▸ ./prog1 4 0.5 10000

▸ ./zombies 20 2 10000 137957

41

CommandLineArguments• Nowwecanunderstandthearguments

passedtothemainfunction(int argc,char*argv[])

• Atthecommandpromptwecangiveinputstoourprogramratherthanmakingqueryingtheuserinteractively:– $./prog140.5100000– $cpbroke.c broke2.c

• Commandlinestringisbrokenatwhitespacesandcopiedintoindividualstringsandthenpackagedintoanarray(argv)

– Eachentryisapointertoastring(char*)

• Argc indicateshowlongthatarraysis(argv[0]isalwaystheexecutablename)

p r o g 1 4 0 . 5 1 0 0 0 0 0

p r o g 1 \0

4

0 . 5

1 0 0 0 0 0

\0

\0

\0

argv[0]argv[1]argv[2]argv[3]

Command line:

240240288300196

288

300

196

Linux shell command line

./prog1 Executable

int main(int argc, char *argv[])

argc = 4 argv = 5a0

5a0

TEXT

TYPICAL COMMAND LINE USAGE

▸ Twentyone assignment uses command line args

▸ At beginning of main(), check to see if argc is correct

▸ Implies the user put in the right # of arguments

▸ Remember, each argument is a C-string

▸ String arguments = OK

▸ Numeric arguments: need to convert

▸ int atoi() (ASCII to Int)

▸ double atof() (ASCII to Floating point)

42

CommandLineArguments• Recommendedusage:

– Uponstartupcheckargc tomakesuretheuserhasinputthedesirednumberofargs (remembertheexecutablecountsasoneoftheargs.)

• Problem:– Eachargumentisatextstring…for

numberswewantitsnumericrepresentationnotitsASCIIrepresentation

– cstdlib defines:atoi()[ASCIItoInteger]andatof()[ASCIItofloat/double]

– Eachofthesefunctionsexpectsapointertothestringtoconvert

#include <iostream>#include <cstdlib>using namespace std;

// char **argv is the same as char *argv[]int main(int argc, char **argv){int init, num_sims;double p;if(argc < 4){cout << "usage: prog1 init p sims" << endl;return 1;

}

init = atoi(argv[1]);p = atof(argv[2]);num_sims = atoi(argv[3]);

...

p r o g 1 \0

4

0 . 5

1 0 0 0 0 0

\0

\0

\0

argv[0]

argv[1]

argv[2]

argv[3]

42

CommandLineArguments• Recommendedusage:

– Uponstartupcheckargc tomakesuretheuserhasinputthedesirednumberofargs (remembertheexecutablecountsasoneoftheargs.)

• Problem:– Eachargumentisatextstring…for

numberswewantitsnumericrepresentationnotitsASCIIrepresentation

– cstdlib defines:atoi()[ASCIItoInteger]andatof()[ASCIItofloat/double]

– Eachofthesefunctionsexpectsapointertothestringtoconvert

#include <iostream>#include <cstdlib>using namespace std;

// char **argv is the same as char *argv[]int main(int argc, char **argv){int init, num_sims;double p;if(argc < 4){cout << "usage: prog1 init p sims" << endl;return 1;

}

init = atoi(argv[1]);p = atof(argv[2]);num_sims = atoi(argv[3]);

...

p r o g 1 \0

4

0 . 5

1 0 0 0 0 0

\0

\0

\0

argv[0]

argv[1]

argv[2]

argv[3]

TEXT

STRING FUNCTION LIBRARY▸ #include <cstring> gets you lots of useful C-string functions

▸ int strlen(char *dest);

▸ int strcmp(char *s1, char*s2);

▸ Return 0 if equal, >0 if s1 would come lexicographically before s2, <0 otherwise

▸ char* strcpy(char *dest, char *src);

▸ Copy src to dest

▸ char* strcat(char *dest, char *src);

▸ Copy src to the end of dst and NULL terminate. Aka concatenate src onto dest

▸ char* strchr(char *str, char c);

▸ Return a pointer to the first occurrence of c in str, NULL otherwise

TEXT

IN CLASS EXERCISES

▸ cmdargs_sum

▸ cmdargs_smartsum

▸ cmdargs_smartsum_str

▸ toi

TEXT

WHY USE POINTERS?

▸ To change a variable(s) local to one function in another function

▸ a.k.a. pass-by-pointer or pass-by-reference

▸ When using large data structures, pass by pointer avoids making copies

▸ Copies aren’t free: memory use and time

▸ When we need a variable address. We don’t know, or can’t know the address of a desired memory address at compile time

▸ Accessing embedded hardware registers

TEXT

DYNAMIC MEMORY - MOTIVATION

▸ Writing a program to calculate student grades.

▸ int scores[??];

▸ How many students?

▸ The following is bad form/unsupported

▸ int num; cin >> num; int scores[num];

▸ Also, variables declared on the stack die when that function finishes…

▸ How to solve this problem?

TEXT

DYNAMIC MEMORY - ANALOGY

▸ Public storage

▸ Need more space? Go rent a locker.

▸ Need more? Rent another.

▸ Had a garage sale, don’t need them any more?

▸ Terminate the lease.

▸ Locker becomes available to someone else

TEXT

DYNAMIC MEMORY

▸ Dynamic memory is on-demand-memory

▸ When you need some memory you allocate what you need

▸ This memory is allocated on the heap

▸ When you are done, you release it back to the heap

▸ Heap memory is visible (valid) any where in your program

▸ So any function with a pointer to heap-allocated memory can use it

TEXT

THE HEAP

▸ The heap is an area of memory that can grow/shrink as your program executes

▸ i.e. it is “dynamic”

▸ Stack grows towards lower addresses (up on the drawing)

▸ Heap grows towards higher addresses (down)

▸ In rare cases they collide - PANIC ENSUES

▸ or your program crashes

49

DynamicMemory&theHeap

• Codeusuallysitsatlowaddresses

• Globalvariablessomewhereaftercode

• Systemstack(memoryforeachfunctioninstancethatisalive)– Localvariables

– Returnlink(wheretoreturn)

– etc.

• Heap:Areaofmemorythatcanbeallocatedandde-allocatedduringprogramexecution(i.e.dynamicallyatrun-time)basedontheneedsoftheprogram

• Heapgrowsdownward,stackgrowsupward…– Inrarecasesoflargememoryusage,theycould

collideandcauseyourprogramtofailorgenerateanexception/error Memory

Code

Stack (area for

data local to a function)

Globals

0

Heap

fffffffc

TEXT

C++ DYNAMIC MEMORY ALLOCATION

▸ ‘new’ operator

▸ Use to allocate memory from the heap. Either single variables or arrays

▸ ‘new’ returns a pointer to the newly allocated memory

▸ The pointer is of the appropriate type

double *dptr = new double; //allocate 8 bytes to hold one double

int* array = new int[100]; //allocate an array of 100 integers

TEXT

C++ DYNAMIC MEMORY DEALLOCATION

▸ `delete` operator gives the memory back

▸ Delete is a misnomer! Nothing is deleted or zero’d out

▸ Calling `delete` on a pointer makes the memory available again, so it can be reused

▸ Note the syntax [] for arrays

delete dptr; //give back the 8 bytes

delete[] array; //give back the memory allocated for the entire array

TEXT

DYNAMIC MEMORY USAGE53

DynamicMemoryAllocationint main(int argc, char *argv[]){int num;

cout << “How many students?” << endl;cin >> num;

int *scores = new int[num];// can now access scores[0] .. scores[num-1];return 0;

}

Memory

20bc420bc820bcc20bd0

20bc0 0000000000

…Code

local vars

Globals

0

Heap

fffffffc

scores[0]

new allocates:

scores[4]

scores[1]scores[2]scores[3]

int main(int argc, char *argv[]){int num;

cout << “How many students?” << endl;cin >> num;

int *scores = new int[num];// can now access scores[0] .. scores[num-1];delete [] scoresreturn 0;

}

TEXT

DYNAMIC MEMORY CHECKPOINT

_________ data = new int;

_________ data = new char;

_________ data = new char[100];

_________ data = new char*[20];

_________ data = new string;

TEXT

DYNAMIC MEMORY CHECKPOINT

int* data = new int;

char* data = new char;

char* data = new char[100];

char** data = new char*[20];

string* data = new string;

TEXT

DYNAMIC MEMORY USAGE

▸ Dynamic Memory ‘lives’ on heap

▸ Only accessible with the pointer returned from new

56

DynamicAllocation• DynamicAllocation

– Livesontheheap• Doesn'thaveaname,onlypointer/addresstoit

– Livesuntilyou'delete'it• Doesn'tdieatendoffunction

(thoughpointertoitmay)

• Let'sdrawtheseasboxesintheheaparea

// Computes rectangle area, // prints it, & returns itint* area(int, int);void print(int);

int main(){int wid = 8, len = 5, a;area(wid,len);

}

int* area(int w, int l){int* ans = new int;*ans = w * l;return ans;

}

Stack Area of RAM

8 wid0xbf0

main 5 len0xbf4

-73249515 a0xbf8

00400120 Return link

0xbfc

area 8 w0xbe4

5 l0xbe8

004000ca0 Return link

0xbec

0x93c ans0xbe0

Heap Area of RAM

400x93c

56

DynamicAllocation• DynamicAllocation

– Livesontheheap• Doesn'thaveaname,onlypointer/addresstoit

– Livesuntilyou'delete'it• Doesn'tdieatendoffunction

(thoughpointertoitmay)

• Let'sdrawtheseasboxesintheheaparea

// Computes rectangle area, // prints it, & returns itint* area(int, int);void print(int);

int main(){int wid = 8, len = 5, a;area(wid,len);

}

int* area(int w, int l){int* ans = new int;*ans = w * l;return ans;

}

Stack Area of RAM

8 wid0xbf0

main 5 len0xbf4

-73249515 a0xbf8

00400120 Return link

0xbfc

area 8 w0xbe4

5 l0xbe8

004000ca0 Return link

0xbec

0x93c ans0xbe0

Heap Area of RAM

400x93c

56

DynamicAllocation• DynamicAllocation

– Livesontheheap• Doesn'thaveaname,onlypointer/addresstoit

– Livesuntilyou'delete'it• Doesn'tdieatendoffunction

(thoughpointertoitmay)

• Let'sdrawtheseasboxesintheheaparea

// Computes rectangle area, // prints it, & returns itint* area(int, int);void print(int);

int main(){int wid = 8, len = 5, a;area(wid,len);

}

int* area(int w, int l){int* ans = new int;*ans = w * l;return ans;

}

Stack Area of RAM

8 wid0xbf0

main 5 len0xbf4

-73249515 a0xbf8

00400120 Return link

0xbfc

area 8 w0xbe4

5 l0xbe8

004000ca0 Return link

0xbec

0x93c ans0xbe0

Heap Area of RAM

400x93c

56

DynamicAllocation• DynamicAllocation

– Livesontheheap• Doesn'thaveaname,onlypointer/addresstoit

– Livesuntilyou'delete'it• Doesn'tdieatendoffunction

(thoughpointertoitmay)

• Let'sdrawtheseasboxesintheheaparea

// Computes rectangle area, // prints it, & returns itint* area(int, int);void print(int);

int main(){int wid = 8, len = 5, a;area(wid,len);

}

int* area(int w, int l){int* ans = new int;*ans = w * l;return ans;

}

Stack Area of RAM

8 wid0xbf0

main 5 len0xbf4

-73249515 a0xbf8

00400120 Return link

0xbfc

area 8 w0xbe4

5 l0xbe8

004000ca0 Return link

0xbec

0x93c ans0xbe0

Heap Area of RAM

400x93c

Stack Heap

Memory Leak!

TEXT

MEMORY LEAKS

▸ You must keep track of heap allocated pointers!

▸ If you don’t, the memory “leaks”

▸ Allocated, but no way to deallocate

▸ Now this code can delete the memory when finished with it

58

DynamicAllocation• DynamicAllocation

– Livesontheheap• Doesn'thaveaname,onlypointer/addresstoit

– Livesuntilyou'delete'it• Doesn'tdieatendoffunction

(thoughpointertoitmay)

• Let'sdrawtheseasboxesintheheaparea

// Computes rectangle area, // prints it, & returns itint* area(int, int);void print(int);int main(){int wid = 8, len = 5, *a;a = area(wid,len);cout << *a << endl;delete a;

}

int* area(int w, int l){int* ans = new int;*ans = w * l;return ans;

}

Stack Area of RAM

8 wid0xbf0

main 5 len0xbf4

0x93c a0xbf8

00400120 Return link

0xbfc

Heap Area of RAM

400x93c

TEXT

POINTER TIP!

▸ Never return a pointer to a local variable!

59

PointerMistake• Neverreturnapointertoalocalvariable // Computes rectangle area,

// prints it, & returns itint* area(int, int);void print(int);

int main(){int wid = 8, len = 5, *a;a = area(wid,len);cout << *a << endl;

}

int* area(int w, int l){int ans;ans = w * l;return &ans;

}

Stack Area of RAM

8 wid0xbf0

main 5 len0xbf4

-73249515 a0xbf8

00400120 Return link

0xbfc

area 8 w0xbe4

5 l0xbe8

004000ca0 Return link

0xbec

40 ans0xbe0

Heap Area of RAM

59

PointerMistake• Neverreturnapointertoalocalvariable // Computes rectangle area,

// prints it, & returns itint* area(int, int);void print(int);

int main(){int wid = 8, len = 5, *a;a = area(wid,len);cout << *a << endl;

}

int* area(int w, int l){int ans;ans = w * l;return &ans;

}

Stack Area of RAM

8 wid0xbf0

main 5 len0xbf4

-73249515 a0xbf8

00400120 Return link

0xbfc

area 8 w0xbe4

5 l0xbe8

004000ca0 Return link

0xbec

40 ans0xbe0

Heap Area of RAM

60

PointerMistake• Neverreturnapointertoalocalvariable• Pointerwillnowpointtodeadmemoryand

thevalueitwaspointingatwillbesooncorrupted/overwritten

• Wecallthisadanglingpointer(i.e.apointertobadordeadmemory)

// Computes rectangle area, // prints it, & returns itint* area(int, int);void print(int);

int main(){int wid = 8, len = 5, *a;a = area(wid,len);cout << *a << endl;

}

int* area(int w, int l){int ans;ans = w * l;return &ans;

}

Stack Area of RAM

8 wid0xbf0

main 5 len0xbf4

0xbe0 a0xbf8

00400120 Return link

0xbfc

Heap Area of RAM

TEXT

IN CLASS EXERCISE

▸ ordered_array

TEXT

MULTIDIMENSIONAL ARRAYS AND DYNAMIC MEMORY

▸ How to allocate 2D, 3D or more arrays?

▸ int* image = new int[x][y]; //This won’t compile

▸ Solution? Higher dimensions are allocated as pointers, only lowest dimension is data type.

▸ This is what we did with the wordBank[] in lab 7.

TEXT

ALLOCATING MULTIDIMENSIONAL ARRAYS

▸ Example: allocate image array X, Yint** image = new int*[X];

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

{

image[i] = new int[Y];

}

//Then the syntax to use is the same

image[i][j] = 0;

TEXT

ALLOCATING 3D EXAMPLE

▸ Allocate array sized X, Y, Zint*** array = new int**[X];

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

{

array[i] = new int*[Y];

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

{

array[i][j] = new int[Z];

}

}

//now we can use it

array[1][2][3] = 0;