Upload
derick-young
View
230
Download
2
Embed Size (px)
Citation preview
Review: Pointers & Arrays, Heap & Call Stack
CS 1037 Fundamentals of Computer Science II
2
Pointers & Arrays are Crucial
• Needed to process and manage data• Appear everywhere in real C++ code
bool EffectAmplify::ProcessSimpleMono(float *buffer, sampleCount len){ sampleCount i; for (i = 0; i < len; i++) { buffer[i] = (buffer[i] * ratio); } return true;}
Real Life™ example: “amplify volume” effect from Audacity project
pointer
pointer as array
http://code.google.com/p/audacity/source/browse/audacity-src/trunk/src/effects/Amplify.cpp
3
The C++ Programmer’s Brain .
• Able to parse crazy syntax, subconsciously• Understand many programming concepts
// TODO(apatrick): It looks like all the resources allocated here leak.// We should fix that.bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) { scoped_ptr<CommandBufferService> command_buffer( new CommandBufferService); if (!command_buffer->Initialize(kCommandBufferSize)) return false;
GPUProcessor* gpu_processor(new GPUProcessor(command_buffer.get())); if (!gpu_processor->Initialize(hwnd, gfx::Size(), NULL, 0)) return false; ...http://src.chromium.org/viewvc/chrome/trunk/src/gpu/demos/framework/window.cc?revision=47041&view=markup
Real Life™ example: code by Google engineer for upcoming version of Chrome
classes
templatespointers
namespaces
dynamic allocation (heap)
constructorsmember functions
5
The C++ Programmer’s Brain .
• Helps to imagine computation from computer’s perspective– address space, pointers, CPU
• Helps to understand basic efficiency–heavy influence on design of C/C++–unfortunate for a teaching language : (
CPU
memory
6Creator of C++ is preoccupied with efficiency...
7
Pointers
• You MUST understand pointers. 1. the computation they represent (CPU does what?)2. the syntax: int* x versus *x
void negate(int x) { x = -x;}
void main() { int b = 5; negate(b); cout << b;}
x is copy of an intvoid negate(int* x) { *x = -(*x);}
void main() { int b = 5; negate(&b); cout << b;}
x is pointer to an int
FAIL
8
• Giant array of bytes• Everything is a number
x
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
mov ret
How Memory Works
C7
05
00
18
00
00
C3
????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
int x;
void main() { x = 7;}
... mov [0018],7 ; store 0 at 0018ret ; return
machine code (16-bit Intel)
CPU
C7
05
00
18
00
07
C3
00
07
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
CPU16-bit “address space”
9
• A pointer variable is... just a variable!– an integer value interpreted as memory location
x y
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
Pointers – Behind the Curtain
int x;int* y = &x;void main() { *y = 7;}
retmov mov
mov eax,[001a] ; eax = 0018mov [eax],7 ; mov [0018],7ret
CPU CPU
A1
00
1a
C7
00
00
07 C3
???? 00
18
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
A1
00
1a
C7
00
00
07 C3
???? 00
18
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
???? 00
18
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
A1
00
1a
C7
00
00
07 C3
00
07
00
18
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
CPU????eax00
18
eax
...
10
Pointers are Typed
• All pointers are just integers underneath, so why doesn’t C++ compiler allow this...?
• Because int* p says two things about p1. p is a pointer variable2. memory p points to contains value of type int
• Special void* type says “I don’t know what I’m pointing at. Could be anything.”
int* p;float* q = p; // make q point at same thing as p
11
Arrays
• Basic form of list – and lists are crucial!
• Pros:– fast access to any item– no wasted memory (potentially)
• Cons:– slow to resize– slow to insert/erase items
for (int i = 0; i < num_slides; ++i) // Code by guy/girl draw_thumbnail(slide[i]); // at Microsoft.
12
Arrays in C
• Many things you’d expect to work don’t :(
• Très annoying. • C++ provides way to create smarter arrays – we will do this by writing dynarray later on
int p[3]; // OKint q[3] = { 0,2,5 }; // OKint r[] = { 0,2,5 }; // OKint s[] = p; // doesn't compile: cannot copyint t[]; // doesn't compile: size unspecifiedint[] u; // doesn't compile: Java!?int size = 3; int v[size]; // doesn't compile: size unknown
13
• ‘Array’ implies ‘consecutive locations’– item[i+1] located right after item[i]
v
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
Arrays – Behind the Curtain
int v[3];
void main() { v[0] = 0; v[2] = 7;}
mov retmov
C7
05
00
18
00
00
C7
05
00
1c
00
07
C3
????????????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
... mov [0018],0mov [001c],7ret
CPU CPU CPU
C7
05
00
18
00
00
C7
05
00
1c
00
07
C3
00
00
????????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
C7
05
00
18
00
00
C7
05
00
1c
00
07
C3
00
00
???? 00
07
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
machine code (16-bit Intel)
14
i v
Arrays – Behind the Curtain
????????????0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
...mov eax,[0010] ; load i into cpumov [0018+2*eax],eax ; v[i] = i inc [0010] ; ++i
int v[3];
void main() { for (int i = 0; i < 3; ++i) v[i] = i;}
????eax
00
00
????????????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f0
000
eax
00
00
00
00
????????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
00
01
00
00
????????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f0
001
eax
00
01
00
00
00
01
????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
00
02
00
00
00
01
????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f0
002
eax
00
02
00
00
00
01
00
02
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
15
Static Arrays in C++
• Size must be known “at compile-time”
• Can be multi-dimensional
• ‘Almost’ a pointer
// 3D coordinates (x,y,z)float p[3]; // positionfloat v[3]; // velocity
char* day_names[7] = { "Sun","Mon","Tue","Wed", "Thu","Fri","Sat"};
float* p0 = p; // p 'decays' to &p[0] if (p0 == &p[0]) cout << "same pointers!"; // prints!
float positions[100][3]; // one hundred 3D positionspositions[99][0] = 0; // set x = 0 on last coordinate
16
somewhere
• Size can be computed “at run-time”• Create array with new[] operator
• Need pointer to remember array location!
dim
Dynamic Arrays in C++
int dim = 3;
void main() { new int[dim]; // allocate 3 integers, somewhere}
00
03
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
00
03
????????????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
17
• Construct array with new[] operator• Destruct array with delete[] operator
somewherepos
dim
Dynamic Arrays in C++
int dim = 3;
void main() { int* pos = new int[dim]; // construct array of int pos[0] = 5; pos[1] = 7; pos[2] = 0; delete[] pos; // destruct array}
00
03
00
18
????????????
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
00
03
00
18
00
05
00
07
00
00
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
18
• A pointer variable is... just a variable!– an integer value interpreted as memory location
pos
Pointers – Behind the Curtain
...mov eax,[000c] ; load posmov [eax+0],5mov [eax+2],7mov [eax+4],0
int* pos = ...
pos[0] = 5;pos[1] = 7;pos[2] = 0;
00
18
eax00
18
00
05
00
07
00
00
0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
000a
000b
000c
000d
000e
000f
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
001e
001f
mov movPointer can be treated like array! How it works...
19
Size of Dynamic Arrays
• Pointer doesn’t know size of array– debugger doesn’t know size either (annoying!)
QuickWatch: Shift+F9
20
• Hard to visualise program state as giant 1D array of numbers
• So draw boxes and arrows instead!
Memory Diagrams
int dim = 3;
void main() { int* pos = new int[dim]; pos[0] = 5; pos[1] = 7; pos[2] = 0; delete[] pos; }
program
CPUdim
pos
3
570
memory diagram before delete[]
21
Memory Diagrams
int x,y;int* p = 0; p = &x; // &x means "the address of x", e.g. 0018*p = 0; // *p means "memory p is pointing at" p = 0;
Memory diagram shows program state – a moment in time
x????
before 1
y????
p0
123
x????
before 2
y????
p0018
x0
before 3
y????
p0018
x0
after 3
y????
p0
22
Memory Diagrams
int* pos = new int[3]; for (int i = 0; i < 3; ++i) { int* p = &pos[i]; *p = i;}delete[] pos;
12
3
Example for blackboard...
before 1 (i=0)
pos ????
????????
0i
before 2 (i=0)
pos ????
????????
0i
p
before 1 (i=1)
pos 0
????????
1i
after 3
pos
?...
23
Array[Index] == *(Pointer+Index)
• Can treat v like array, or like pointer
• These loops are equivalent:for (int i = 0; i < 5; ++i) // clear :) v[i] = 0;
for (int i = 0; i < 5; ++i) // less clear :\ *(v+i) = 0;
for (int* p = v; p < v+5; ++p) // hard to read :( *p = 0;
v[4] = 0; // "5th item of array v" = 0*(v+4) = 0; // "item at location v+4" = 0 (5th item!!)
int v[5] = { 40, 50, 60, 80, 100 };
24
• Memory divided into 4 different areas:– machine code (don’t care)– globals– call stack– heap
Heap & Call Stack
dim
pos
3
570
int dim = 3;
void main() { int* pos = new int[dim]; pos[0] = 5; pos[1] = 7; pos[2] = 0; delete[] pos; }
call stack
globals
heap
main
25
Call Stack
• All local variables live in this memory, e.g.int* create_int_array(int size) { int* array = new int[size]; return array;}
arguments are also local
local heap (neither local, nor global)
array????????????
call stack heap
function that called create_int_array
create_int_array
size3
CPU
26
Call Stack
• Remembers path CPU took, and state of all functions CPU passed through.void main() { int size = 3; int* grades = create_int_array(size); grades[2] = 90;}
array01c0 ????
????????
stack heap
main
create_int_array
size3
grades????
size3
CPU passed through here
27
Call Stack
• Function’s local variables all destroyed when function returns!void main() { int size = 3; int* grades = create_int_array(size); grades[2] = 90;}
????????????
call stack heap
main
grades01c0
size3
CPUCPU
90
28
Exercise
• Draw memory diagram at 1, 2, and 3void negate(int* x) { *x = -(*x);}
void main() { int b = 5; negate(&b); cout << b;}
12
3
29
Neat Fact (don’t need to know)
• In multi-threaded program, each thread uses its own stack
stack 1 heap
blahCPU 1
CPU 2
stack 2
someplace
whatever
“laa dee daa” “doop dee doo”
30
Heap
• In real C++ programs, heap contains almost all persistent state– Any data that lives longer than function that
created it, e.g. onMouseClick creates arrow
• C++ programmers use heap all the time– Firefox code calls new in 4000 places– Chrome code calls new in 6000 places
31
Heap – More Examples
• Web browser needs to create tabs on the fly
• Also needs to download images on the flyint width = jpeg->wd;int height = jpeg->ht;char* pixels = new char[width*height*3];decompress_jpeg(jpeg,pixels);
FirefoxTab* tab = new FirefoxTab;tab->loadPage("cuteoverload.com");tabList->add(tab);
32
Heap – C++ Formalities
• Subtly different syntax:
• Use new and delete together
• Use new[] and delete[] together
double* v = new double(3.0); // 1 double with value 3.0 ...delete v; // finished with v
double* v = new double[3]; // 3 doubles with value ????...delete[] v; // finished with v
new type; // 1 var of type type, uninitializednew type(); // 1 var, initialized to zeronew type(value); // 1 var, initialized to copy of valuenew type[size]; // array of size vars, uninitialized
33
You’re doing it wrong!
• Don’t mismatch delete and new[]
• Don’t do this...
int* v = new int;delete[] v; // use delete
int* v = new int[size];delete v; // use delete[]
ptr = NULL;delete ptr;
ptr = NULL;delete NULL;
delete ptr;ptr = 0; // optional
FAIL
OMG FAIL!!
OKdelete &ptr; FAIL
ptr ptr0
after
memory leak!
before
(appeared in cs1037 assignment)
34
Arrays of Pointers
• Very common in real C++ code, e.g.– list of objects (tabs, buttons, monsters)– list of arrays (sound data, grade data,...).double* sound[2]; // stereo patternsound[0] = new double[num_samples]; // left sound[1] = new double[num_samples]; // right
sound
????????
????
stack heap
...????????
????
...
35
Arrays of Pointers
• Can also have dynamic array of pointers– pointers in heap => need pointer-to-a-pointer!– double** means “pointer to a double*”double** tracks = new double*[num_tracks]; // array offor (int i = 0; i < num_tracks; ++i) // sound tracks[i] = new double[num_samples]; // patterns
tracks
????
????
stack heap...
????
????
......
????
????...
each is a double*
each is a double
one double**
36
Summary
• Memory is giant 1D array of numbers– some numbers (pointers) are just to remember the
location of other numbers (data, objects)
• Programs break it into four parts:– code, globals, call stack, heap
• Call stack remembers who’s-calling-whom– all local variables live somewhere on stack– function return => all its local variables forgotten
• Understanding this stuff is really important!