Vous êtes sur la page 1sur 56

11 - Pointers and Dynamic Memory

All
Allocation
i
COL 100 - Introduction to Computer
p
Science
II Semester 2015-2016
Department of Computer Science and Engineering
Indian Institute of Technology Delhi

Using Object Across Multiple


Functions
Need object t1
across functions
Where should
we declare
Employee t1;?
t1; ?
Employee

April 2016

class Employee {
int details [10000];
public:
bli
void print ();
};
void f () { // use t1
}
void g () { // print details
t1 print ();
t1.print
}
int main () {...
f (); // use t1
g (); // use t1
h (); // dont need t1 any more
}

(C) P. R. Panda, IIT Delhi

Objects
b
Sometimes Waste Space
class
l
E
Employee
l
{
int details [10000];
public:
void print ();
} t1; // global object
void f () {{...}}
void g () {t1.print ();}
int main () {...
f ();
() // use t1
g (); // use t1
h (); // dont need t1 any more
}

class Employee {
int details [10000];
public:
void print ();
};
void f (Employee &t) {...}
void
id g (Employee
(E l
&t) {t1
{t1.print
i t ()
();}}
int main () {
Employee
p y t1; // local to main
f (t1); // use t1
g (t1); // use t1
h (); // dont
don t need t1 any more
}

Better Design
I both
In
b th cases, t1 occupies
i memory even after
ft it iis useless
l
(d
(during
i h())
April 2016

(C) P. R. Panda, IIT Delhi

Minimising the Memory Footprint


Need to conserve memory
occupy only as much memory as
necessaryy

Improves overall system performance


releases memory to other programs
better cache performance

April 2016

(C) P. R. Panda, IIT Delhi

Define Appropriate
pp p
Scopes
p

Enclose in tight
scope
t1 de-allocated
de allocated
(freed) in
stack after end
of scope

April 2016

class Employee {
int details [10000];
public:
bli
void print ();
};
void f (Employee &t) {...}
void g (Employee &t) {...}
int main ()
{
int a;
{
Employee t1; // local to main
f (t1); // use t1
g (t1); // use t1
}
h (); // dont need t1 any more
}

(C) P. R. Panda, IIT Delhi

class Employee {
int details [10000];
public:
void print ();
};
void
id f (Employee
(E l
&t) {{...}}
void g (Employee &t) {...}
int main ()
{
Employee t0;
{
Employee t1;
f (t1); g (t1);
t3
}
{
Employee t2;
t0 t0
f (t2); g (t2);
}
Employee t3;
h ()
(); // dont
d t need
d t1,t2
t1 t2
} Delhi
(C) P. R. Panda, IIT

Early
y DeDe-allocation
Memory space
occupied by t1
can be
b re-used
d
for t2, t3

Memory
Occupied

t0

April 2016

t1

t2

t0

t0
time

Scopes may not be aligned


What if object
creation was
conditional?
Need more
general
mechanism

April 2016

class Employee {
int details [10000];
public:
void print ();
}
};
void f () {...}
void g () {t1.print ();}
int main () {...
if (cond) {
f ()
(); // t1 created conditionally
y
} else {p ();}
if (cond) {
g (); // access t1 if it exists
} else {q ();}
h (); // dont need t1 any more
}
(C) P. R. Panda, IIT Delhi

Dynamic Memory Allocation


Should be able to
allocate memory
when we need...
...and De-allocate
when we need
Need additional
syntax
single declaration
statement not enough
April 2016

class
l
E
Employee
l
{
int details [10000];
public:
void print ();
};
void f () {{...}}
void g () {t1.print ();}
int main () {...
if (cond) {
// CREATE t1 HERE
f ();
} else {p ();}
if (cond) {
g ();
// FREE t1 HERE
} else {q ();}
h (); // dont need t1 any more
}

(C) P. R. Panda, IIT Delhi

The POINTER Data Type


A Pointer points-to an object
implemented as Address of the Object

* Operator declares Pointer


& Operator
p
g
gives Address of
object
Space occupied by pointer:
4B / 8B (bytes required for an address
in processor)
independent of size of type it points to
size of ep unrelated to size of t1

April 2016

(C) P. R. Panda, IIT Delhi

class Employee {
int details [10000];
public:
void print ();
};
int main () {
Employee t1;

Employee
p y *ep;
p;
ep = &t1;
}

The POINTER in Memory


ep contains start address of t1
class Employee {
int id;
char name [100];
};
int main () {
E l
Employee
t1
t1;

100
104

t1.id

t1

t1 name
t1.name
204

100

ep

Employee *ep;
ep = &t1;
}

April 2016

(C) P. R. Panda, IIT Delhi

10

What can a Pointer point to?


Pointer can point to ANY type

April 2016

built-in types
yp ((int, char,...))
user-defined types (class, struct, array,...)
to p
pointer type
yp
to functions!
byte
y address for bool type
yp

(C) P. R. Panda, IIT Delhi

11

Pointer Dereferencing
VALUE accessed through
DEREFERENCING
operator *

a
x

100
104

different from declaration


intt main
a () {
int a = 2;
int *x = &a;
*x
x = 3;
cout << a << *x << x;
} // prints 3 3 100 (in hex)
April 2016

(C) P. R. Panda, IIT Delhi

100
104

100
104

3
100

a
x

100
104

a
x

2
100

a
x
12

Dereferencing a Pointer to
Struct/Class
Struct
/Class
-> operator same as
D f
Dereferencing
i +
Member
*a.b abbreviated to
a->b

April 2016

(C) P. R. Panda, IIT Delhi

class Employee {
public:
p
int id;
char name [100];
};
int main () {
Employee t1;
Employee *ep
ep = &t1;
ep->id = 10;
cout << t1.id; // 10
}

13

Pointer to Pointer
Pointers can be
composed in terms
pointers
of other p
x is pointer to int
y is
i pointer
i t tto
pointer-to-int

April 2016

(C) P. R. Panda, IIT Delhi

int main () {
int a = 2;;
int *x = &a;

int **y = &x;


*x
x = 3; // a = 3
**y = 4; // a = 4
}

100
104
108

2
100
104

a
x
y
14

Pointers and Arrays


Array of pointers
Each array element points to an int
iintt main
i () {
int a = 2;
int *x[4];
x[0] = &a;
*x[0] = 3; // a = 3
x[1]
[ ] = x[0];
[ ];
*x[1] = 4; // a = 4
*x[2] = 5; // ?
}
April 2016

100
104
108
112
116

(C) P. R. Panda, IIT Delhi

2
100
100

a
x[0]
x[1]
[1]
x[2]
x[3]

15

Pointer to an Array
p = a means p points to a[0]
int main () {
i t a[5];
int
[5]

int *p = a;
*p
p = 3; // a[0]
[ ]=3
}

April 2016

100 104
104
108
112
116
120

p
a[0]
a[1]
a[2]
a[3]
a[4]

(C) P. R. Panda, IIT Delhi

100 104
104
3
108
112
116
120

p
a[0]
a[1]
a[2]
a[3]
a[4]

16

Pointer Arithmetic
p++ means p = p + sizeof (int)
int main () {
i t a[5];
int
[5]
int *p = a;
*p = 3; // a[0] = 3

p++;
}

April 2016

100 104
104
3
108
112
116
120

p
a[0]
a[1]
a[2]
a[3]
a[4]

(C) P. R. Panda, IIT Delhi

100 108
104
3
108
112
116
120

p
a[0]
a[1]
a[2]
a[3]
a[4]

17

Pointer Arithmetic
*p++ = 4 means
p 4 , then p
p = p + sizeof (int)
(int)
*p=4,
int main () {
i t a[5];
int
[5]
int *p = a;
*p = 3; // a[0] = 3
p++;
*p++ = 4; // a[1] = 4
}

April 2016

100 108
104
3
108
112
116
120

p
a[0]
a[1]
a[2]
a[3]
a[4]

(C) P. R. Panda, IIT Delhi

100 112
104
3
108
4
112
116
120

p
a[0]
a[1]
a[2]
a[3]
a[4]

18

Pointer Arithmetic
*(p+2) = 6 means set content of
address p
p+2
2*sizeof
sizeof (int)
(int) to 6
int main () {
i t a[5];
int
[5]
int *p = a;
*p = 3; // a[0] = 3
p++;
*p++ = 4; // a[1] = 4
*(p+2)
(p ) = 6;; // a[4]
[ ]=6
}

April 2016

100 112
104
3
108
4
112
116
120

p
a[0]
a[1]
a[2]
[2]
a[3]
a[4]

(C) P. R. Panda, IIT Delhi

100 112
104
3
108
4
112
116
120
6

p
a[0]
a[1]
a[2]
a[3]
a[4]

19

Pointer Arithmetic
q = p+4 means
= (Start
q
(St t address
dd
off t1)
+ 4 * sizeof (Employee)

April 2016

class Employee {
public:
p
int id;
char name [100];
};
int main () {
Employee t1 [10];
Employee *p
p = t1;
Employee *q = p + 4;
q->id = 10; // t1[4] = 10
}

(C) P. R. Panda, IIT Delhi

20

Pointer and Arrays almost


Indistinguishable
g
Array name is just a
C
Constant
t t Pointer
P i t
a is treated as Pointer to int
a [i] is identical to *(a+i)
Cantt assign to a
Can

int main () {
intt a[
a[10];
0];
int *p = a;
a [3] = 5;
cout << p[3]; // 5
cout << *(p+3); // 5
}

a = p would be wrong
a is const Pointer

April 2016

(C) P. R. Panda, IIT Delhi

21

Constant Pointer vs
Pointer to Constant
Pointer to Constant: const int *p;
*p = 10; // not allowed
p = &a; // allowed

Constant Pointer: int *const p;


p = &a; // not allowed
*p = 7; // allowed

Resolve confusion?
Read from Right to Left!
April 2016

(C) P. R. Panda, IIT Delhi

22

Pointer and Array Access


Array Access a[i]
Address calculation
Memory READ or WRITE

Pointer Access *(p+i)


Address calculation
Memory READ or WRITE

April 2016

(C) P. R. Panda, IIT Delhi

23

Pointer and Arrays as


Function Parameters
Array and Pointer
i t h
interchangeable
bl as
function parameter

Identical
void f (int a [ ]) {
a[i] = 3;
*(a+i) = 3;
}

void f (int *a) {


a[i] = 3;
*(a+i) = 3;
}

int main () {
int x [10];
f (x);
( )
}

April 2016

(C) P. R. Panda, IIT Delhi

24

Read--Only Function Parameters


Read
By default, pointer parameter
can be
b modified
difi d
const ensures Read-Only
int f (const int a [ ], int j) {
return *(a+j);
}

Identical
int f (const int *a, int j) {
return a [j];
}

int main () {
int x [10];...
cout << f (x, 4);
}
April 2016

(C) P. R. Panda, IIT Delhi

25

Pointer vs. PointerPointer-toto-Array


Same syntax for
pointer
i t to:
t
scalar
array

int main () {
int x;
int y [10];
int *p;
p = &x; // points to x
p = y; // points to y[0]
p = &y; // also points to y[0]!
}

OK because
interpretation is
address. *p means:
point to scalar
point to array element
April 2016

(C) P. R. Panda, IIT Delhi

26

Pointer and Arrays as


Function Parameters
Array and Pointer
interchangeable as
parameter
function p
Caution: array-style
access on scalar
variable!

April 2016

Identical
void f (int a [ ]) {
a[0] = a[0] + 4;
}

(C) P. R. Panda, IIT Delhi

void f (int *a) {


*a
a += 4;
}

int main () {
int x [10];
f (x);
int y = 2;
f (&y);
}
27

Call by Reference
NOTE: Pointer can be
used
d tto iimplement
l
t
Pass-by-Reference
standard in C
language

In C++,
C
& parameter
is cleaner
Pointer obfuscates
syntax
April 2016

Identical
void f (int &a) {
a += 4;
}
int main () {
int y = 2;
f (y);
}

C++

(C) P. R. Panda, IIT Delhi

void f (int *a) {


*a += 4;
}
int main () {
int y = 2;
f (&y);
}

C
28

So...Why Pointers?
In C++, not really needed for Call-byReference
Useful in Dynamic Memory Allocation

April 2016

(C) P. R. Panda, IIT Delhi

29

Dynamic Memory Allocation


Operator new used for
allocating
ll
ti memory
Outside functions
Stack frame
allocated in heap

OS finds memory,
returns POINTER

class Employee {
public:
int id;
int details [10000];
void p
print ();
};
int main () {
int x [3];
Employee *e;

e = new Employee;
e->id
id = 5;
5
e->print ();

sizeof (Employee)
}
April 2016

(C) P. R. Panda, IIT Delhi

30

Dynamic Memory Allocation


class Employee {
public:
i t id;
int
id
int details [10000];
void print ();
};
int main () {
int x [3];
[ ];
Employee *e;

}
April 2016

Employee

details

e = new Employee;
e->id
e
>id = 5;
e->print ();

id

800
804

204
208
212
216

(C) P. R. Panda, IIT Delhi

800
x[2]
x[1]
x[0]

e
main

31

Dynamic Memory Allocation


Objects allocated through new survive beyond function call
class Employee {
public:
int id;
int details [10000];
void print ();
};
Employee *create_emp () {
E l
Employee
*f = new E
Employee;
l
return f;
}
int main () {
Employee *e = create_emp ();
e->id = 10;
}
April 2016

800
804

10
details

204

800
800

Employee

create_emp:
t
f
main: e

f has disappeared
but the object survives

(C) P. R. Panda, IIT Delhi

32

Freeing Allocated Memory


Operator
delete used for
freeing/
de-allocating
de
allocating
object
object no
longer
accessible
memory may
be overwritten
April 2016

class Employee {public:


int id; int details [10000];
void print ();
};
int main () {
int x [3];
Employee *e;

800
804

id
details

e = new Employee;
e->id = 5;
e->print ();
delete e;
// memory no longer used
}
(C) P. R. Panda, IIT Delhi

204
208
212
216

800
x[2]
x[1]
x[0]

33

Freeing Allocated Memory


x and e still
accessible
can point e to
new allocated
object
may be
b att
different
address

April 2016

class Employee {public:


int id; int details [10000];
void print ();
};
int main () {
int x [3];
Employee *e;
e = new Employee;
...
delete e;
// object no longer used
e = new Employee;
}
(C) P. R. Panda, IIT Delhi

800
804

id
details

900
904

id
details

204
208
212
216

900
x[2]
x[1]
x[0]
34

Dynamically Allocating an Array


800
804

class Employee {public:


int id;
char name [100];
void print ();
}};
int main () {
int n;
Employee *all;
all;
cin >> n;

id
Employee

name
id
name
id
name

all = new Employee [n];


all[4]->id
all[4]
>id = 5;
all[4]->print ();
}
April 2016

212
216
(C) P. R. Panda, IIT Delhi

800

all
n

main

35

Freeing a Dynamically Allocated


Array
Array
800
804

class Employee {public:


int id;
char
h name [100]
[100];
void print ();
};
int main () {
int n;
Employee *all;
cin >> n;

April 2016

Employee

name
id
name
id
name

all = new Employee [n];


...
delete [ ] all;
}

id

212
216

(C) P. R. Panda, IIT Delhi

800

all
n

main

36

Variable Sized Array


Solution for Variable sized array!
standard portable solution
Instead of allocating on stack (int
( int a[n];
a[n];))
non-portable

April 2016

(C) P. R. Panda, IIT Delhi

37

2D Arrays as Function Parameters


Leading dimension
was optional
ti
l iin 2
2-D
D
Identical
array parameter
d l ti
declaration
void f (int a [ ][6]) {
void f (int (*a)[6]) {
a[0][2] += 4;
Can be replaced a[0][2] += 4;
}
}
by pointer
int main () {
int x [10][6];
f (x);
}
April 2016

(C) P. R. Panda, IIT Delhi

38

Dynamically
y
y Allocating
g 2D Arrays
y
int ** f (int rows, int cols) {
int **b;
b = new (i
(intt *)[rows]
*)[
]
for (int i = 0; i < rows; i++) {
b[i] = new int [cols];
}
return b;
}

First allocate array


of (int *)
Then make each
pointer point to a
new int array

could be of
different sizes

Storage NOT
identical to 2D array
more general
structure
April 2016

void g() {
int a [5][6];
int **c = f (5,6);
a[3][2] = 7;
c[3][2]
[3][2] = 7
7;
}

b[3][2]

7
b[3]

(C) P. R. Panda, IIT Delhi

39

Accessing Dynamically Allocated 2D Arrays


Accessing
mechanism is
different
Static 2D array:
address = a + (i*N + j) x
sizeof (int)
Store at (address)

Dynamic
D
i 2D array?
?
address = ?
Store at (address)

Advantage of dynamic
2D a
arrays?
ays
April 2016

int ** f (int rows, int cols) {


int **b;
b = new (i
(intt *)[rows]
*)[
]
for (int i = 0; i < rows; i++) {
b[i] = new int [cols];
}
return b;
}

b
void g() {
int a [5][6];
int **c = f (5,6);
a[3][2] = 7;
c[3][2]
[3][2] = 7
7;
}

b[3][2]

7
b[3]

(C) P. R. Panda, IIT Delhi

40

De--allocating
De
g 2D Arrays
y
Reverse
sequence:
first
fi d
delete
l
allll
int arrays
finally delete
int* array

Why different
sequence?

int ** g (int **b, int rows, int cols) {


for (int i = 0; i < rows; i++) {
delete [ ] b[i];
}
delete [ ] b;
}

b[3][2]

void g() {
int a [10][20];
int **c = f (10,20);
g (c);
}

b[3]
April 2016

(C) P. R. Panda, IIT Delhi

41

Precise Control over Memory


Individual statements
f controlling
for
t lli
memory allocation
and
d ffreeing
i
instead of relying on
scope

April 2016

class Employee {public:


int details [10000];
void print ();
};
int main () {
if (cond) {
// CREATE t1 HERE
f ();
} else {p ();}
if (cond) {
g ();
// FREE t1 HERE
} else
l {{q ()
();}}
h (); // dont need t1 any more
}

(C) P. R. Panda, IIT Delhi

42

Precise Control over


Memory
new and delete
operators
t
are
independent of scope
Initialise to 0
Check if 0
non-zero means
object is ALLOCATED
no object at address 0

April 2016

class Employee {public:


int details [10000];
void print ();
};
int main () {
Employee *e = 0;
if (cond) {
// CREATE
C
t1
1 HERE
e = new Employee;
f ();
} else {p ();}
if (e) {
g ();
// FREE t1 HERE
delete e;
e = 0;
} else {q ();}
h (); // dont need t1 any more
}

(C) P. R. Panda, IIT Delhi

43

Dynamic Allocation in
Cl
Class
Constructors
C
tu t
Constructor
parameters
passed
d as iin
normal objects

April 2016

class Employee {public:


int id;
int details [1000];
void
odp
printt ();
Employee (int k) {
id = k;
for (int i = 0; i < 1000; i++) {
details [i] = 0;
}
}
};
int main () {
E l
Employee
e1
1 (10)
(10);
Employee *e2 = new Employee (20);
}
(C) P. R. Panda, IIT Delhi

44

Dynamic Allocation in
Cl
Class
Constructors
C
tu t
Variable-sized
Objects can be
allocated
ll
t d iin
Constructor
instead of
using
g fixed
array size
((details [[1000])
])

April 2016

class Employee {public:


int id;
id
int *details;
void print ();
Employee (int k, int n) {
id = k;
details = new int [n];
for (int i = 0; i < n; i++) {
details [i] = 0;
}
}
};
int main () {
Employee e1 (10, 5);
Employee *e2 = new Employee (20, 6);
}
(C) P. R. Panda, IIT Delhi

45

Class Destructors
Object deletion
done in Class
DESTRUCTOR
Called when object
j
goes out of scope
e.details
e details deleted at
end of function f

April 2016

class Employee {public:


int id;
int *details;
void print ();
Employee (int i,
i int n) {
id = i;
details = new int [n];
for (int i = 0;
0 i < n;
n i++) {
details [i] = 0;
}
}
~Employee () {delete [ ] details;}
};
int f () {
Employee e (10, 5); ...
}

(C) P. R. Panda, IIT Delhi

46

Class
D tu t
Destructors
Destructor also
called when
object is explicitly
deleted (p)
Only objects
allocated via new
(details) need
deletion
no need to delete
member arrays (t)
April 2016

class
l
E
Employee
l
{{public:
bli
int id;
int t [10];
int *details;
void print ();
Employee
p y ((int i, int n)) {{...}}
}
~Employee () {delete [ ] details;}
};
Employee *f () {
Employee e (10, 5);
return new Employee (6,40);
(6 40);
}
int main () {
Emplo ee *p = f ();
Employee
()
delete p;
}
(C) P. R. Panda, IIT Delhi

47

Stack and Heap Memory


OS allocates space to Program for:
code
data
static: globals, stack
dynamic

OS manages a fixed total memory space


How should it allocate memory to programs?
distribute equally?
needs may not be equal
April 2016

(C) P. R. Panda, IIT Delhi

48

How much memory for a Program?


Can compiler figure this out?
Code?
fixed size

Static data (Global + Local objects)?


Global: fixed size
Local: variable (function call sequence is dynamic)

Dynamic data?
variable size

April 2016

(C) P. R. Panda, IIT Delhi

49

Stack and Heap Memory


Fixed amount of
Global+Stack memory
given to every program
Global / Code size is
fixed
Stack size =
Total Global Code

Heap
p shared
among all programs

Program P1
Heap
Stack
Program P1
Program P2

Global
Code

(simplified view)
April 2016

(C) P. R. Panda, IIT Delhi

50

Problems with Pointers


Low-level detail
address part of HW implementation, not a
programming
p
g
g language
g g concept
p

Interferes with program analysis


pointer can point to ANY object
with casting, even other types

Programming problems
dereferencing invalid pointers
April 2016

(C) P. R. Panda, IIT Delhi

51

Caution with Pointers!


Dereferencing
g Invalid Pointers
Uninitialised Pointer
Access
leads to obscure runrun
time errors
not caught by compiler

int main () {
int a = 2;
int *x;
*x
x = 3;
}

100
104

int main () {
int a = 2;
int *x; ...
if (a) x = &a;
* =3
*x
3;
}
2

a
x

Tries to write 3 to
garbage address
April 2016

(C) P. R. Panda, IIT Delhi

52

Dereferencing Invalid Pointers


int main ()
{
int *x;
{
int b;
x = &b;
} // b out of scope
int c; // at bs address?
*x = 3;; // may
y cause c=3
}

Reference to dead
j
objects
unexpected values taken
by unrelated variables
address remembered in x
even though variable is
dead

104
April 2016

100
104 100

b
x

104 100

(C) P. R. Panda, IIT Delhi

100
104 100

c
x

100 3
104 100
53

c
x

Referencing Deleted Objects


Programmer not
prevented from
p
accessing freed
object
through pointer

April 2016

...
int main ()
{
Employee *x = new Employee;
...
delete x;
...
x->id = 5; // Danger. Freed object
}

(C) P. R. Panda, IIT Delhi

54

Memory Leaks
Memory leaked
if not freed after
allocation
may lead to run
runtime out-ofmemory errors
memory
causing system
crash
h

April 2016

...
int main ()
{
Employee *x;
int n;
for (int i = 0; i < 1000; i++) {
cin >> n;
x = new Employee [n];
// x not de
de-allocated
allocated
}
}

Objects allocated
but never freed

(C) P. R. Panda, IIT Delhi

55

Alternatives: Java Programming


Language
g g
Gets rid of pointers completely
Issue with memory allocation
Automatic memory management
Garbage Collection
Run-time environment attempts to reclaim
memory once in a while
Simpler for programmer, but less efficient
April 2016

(C) P. R. Panda, IIT Delhi

56

Vous aimerez peut-être aussi