CS
61C:
Great
Ideas
in
Computer
Architecture
Introduc)on
to
C,
Part
II
Instructors:
Krste
Asanovic
&
Vladimir
Stojanovic
h>p://inst.eecs.Berkeley.edu/~cs61c/sp15
1
Review:
Components
of
a
Computer
Memory
Processor
Input
Enable?
Read/Write
Control
Program
Datapath
Address
PC
Bytes
Write
Registers
Data
ArithmeLc
&
Logic
Unit
Read Data
Output
(ALU)
Data
Processor-‐Memory
Interface
I/O-‐Memory
Interfaces
2
Address
vs.
Value
• Consider
memory
to
be
a
single
huge
array
– Each
cell
of
the
array
has
an
address
associated
with
it
– Each
cell
also
stores
some
value
– Do
you
think
they
use
signed
or
unsigned
numbers?
NegaLve
address?!
• Don’t
confuse
the
address
referring
to
a
memory
locaLon
with
the
value
stored
there
101
102
103
104
105
...
...
23
42
...
3
Pointers
• An
address
refers
to
a
parLcular
memory
locaLon;
e.g.,
it
points
to
a
memory
locaLon
• Pointer:
A
variable
that
contains
the
address
of
a
variable
LocaLon
(address)
101
102
103
104
105
...
...
23
42
104
...
x
y
p
name
4
Pointer
Syntax
• int *x;!
– Tells
compiler
that
variable
x
is
address
of
an
int!
• x = &y;!
– Tells
compiler
to
assign
address
of
y
to
x!
– &
called
the
“address
operator”
in
this
context!
• z = *x;!
– Tells
compiler
to
assign
value
at
address
in
x
to
z!
– *
called
the
“dereference
operator”
in
this
context!
5
CreaLng
and
Using
Pointers
• How
to
create
a
pointer:
&
operator:
get
address
of
a
variable
int *p, x;
Note
the
“*”
gets
used
p
?
x
?
2
different
ways
in
this
example.
In
the
x = 3;
declaraLon
to
indicate
p
?
x
3
that
p
is
going
to
be
a
pointer,
and
in
the
p = &x;
printf
to
get
the
p
x
3
value
pointed
to
by
p.
• How
get
a
value
pointed
to?
“*”
(dereference
operator):
get
the
value
that
the
pointer
points
to
!printf(“p points to %d\n”,*p); !
6
Using
Pointer
for
Writes
• How
to
change
a
variable
pointed
to?
– Use
the
dereference
operator
*
on
leg
of
assignment
operator
=
p
x
3
*p = 5; p
x
5
7
Pointers
and
Parameter
Passing
• Java
and
C
pass
parameters
“by
value”
– Procedure/funcLon/method
gets
a
copy
of
the
parameter,
so
changing
the
copy
cannot
change
the
original
void add_one (int x) {
! x = x + 1;
}!
int y = 3;!
add_one(y);!
y
remains
equal
to
3
8
Pointers
and
Parameter
Passing
• How
can
we
get
a
funcLon
to
change
the
value
held
in
a
variable?
void add_one (int *p) {
!*p = *p + 1;
}!
int y = 3;!
add_one(&y);!
y
is
now
equal
to
4
9
Types
of
Pointers
• Pointers
are
used
to
point
to
any
kind
of
data
(int,
char,
a
struct,
a
pointer,
etc.)
• Normally
a
pointer
only
points
to
one
type
(int,
char,
a
struct,
etc.).
– void
*
is
a
type
that
can
point
to
anything
(generic
pointer)
– Use
void
*
sparingly
to
help
avoid
program
bugs,
and
security
issues,
and
other
bad
things!
10
More
C
Pointer
Dangers
• Declaring
a
pointer
just
allocates
space
to
hold
the
pointer
–
does
not
allocate
thing
being
pointed
to!
• Local
variables
in
C
are
not
iniLalized,
they
may
contain
anything
(aka
“garbage”)
• What
does
the
following
code
do?
void f()
{
int *ptr;
*ptr = 5;
}
11
Pointers
and
Structures
tyepdef struct { /* dot notation */
int x; int h = p1.x;
int y; p2.y = p1.y;
} Point;
/* arrow notation */
Point p1; int h = paddr->x;
Point p2; int h = (*paddr).x;
Point *paddr;
/*structure assignment*/
p2 = p1;
Note,
C
structure
assignment
is
not
a
“deep
copy”.
All
members
are
copied,
but
not
things
pointed
to
by
members.
12
Pointers
in
C
• Why
use
pointers?
– If
we
want
to
pass
a
large
struct
or
array,
it’s
easier
/
faster
/
etc.
to
pass
a
pointer
than
the
whole
thing
– Want
to
modify
an
object,
not
just
pass
its
value
– In
general,
pointers
allow
cleaner,
more
compact
code
• So
what
are
the
drawbacks?
– Pointers
are
probably
the
single
largest
source
of
bugs
in
C,
so
be
careful
anyLme
you
deal
with
them
• Most
problemaLc
with
dynamic
memory
management—
coming
up
next
lecture
• Dangling
references
and
memory
leaks
13
Why
Pointers
in
C?
• At
Lme
C
was
invented
(early
1970s),
compilers
ogen
didn’t
produce
efficient
code
– Computers
25,000
Lmes
faster
today,
compilers
be>er
• C
designed
to
let
programmer
say
what
they
want
code
to
do
without
compiler
gepng
in
way
– Even
give
compiler
hints
which
registers
to
use!
• Today,
many
applicaLons
a>ain
acceptable
performance
using
higher-‐level
languages
without
pointers
• Low-‐level
system
code
sLll
needs
low-‐level
access
via
pointers,
hence
conLnued
popularity
of
C
14
Clickers/Peer
InstrucLon
Time
void foo(int *x, int *y)!
{ int t;!
if ( *x > *y ) { t = *y; *y = *x; *x = t; }!
}!
int a=3, b=2, c=1;!
foo(&a, &b);!
foo(&b, &c);!
foo(&a, &b);!
printf("a=%d b=%d c=%d\n", a, b, c);!
!
A:
a=3 b=2 c=1!
B:
a=1 b=2 c=3!
Result
is:
C:
a=1 b=3 c=2!
D:
a=3 b=3 c=3!
E:
a=1 b=1 c=1! 15
Administrivia
• We
can
accommodate
all
those
on
the
wait
list,
but
you
have
to
enroll
in
a
lab
secLon
with
space!
– Lab
secLon
is
important,
but
you
can
a>end
different
discussion
secLon
– Enroll
into
lab
with
space,
and
try
to
swap
with
someone
later
• HW0
due
11:59:59pm
Sunday
2/1
– Right
ager
the
Superbowl…
• Midterm-‐II
now
Thursday
April
9
in
class
16
C
Arrays
• DeclaraLon:
int ar[2];
declares
a
2-‐element
integer
array:
just
a
block
of
memory
int ar[] = {795, 635};
declares
and
iniLalizes
a
2-‐element
integer
array
returns
the
numth
element
17
C
Strings
• String
in
C
is
just
an
array
of
characters
char string[] = "abc";
• How
do
you
tell
how
long
a
string
is?
– Last
character
is
followed
by
a
0
byte
(aka
“null
terminator”)
int strlen(char s[])
{
int n = 0;
while (s[n] != 0) n++;
return n;
}
18
Array
Name
/
Pointer
Duality
• Key
Concept:
Array
variable
is
a
“pointer”
to
the
first
(0th)
element
• So,
array
variables
almost
idenLcal
to
pointers
– char *string
and
char string[]
are
nearly
idenLcal
declaraLons
– Differ
in
subtle
ways:
incremenLng,
declaraLon
of
filled
arrays
• Consequences:
– ar
is
an
array
variable,
but
looks
like
a
pointer
– ar[0]
is
the
same
as
*ar
– ar[2]
is
the
same
as
*(ar+2)
– Can
use
pointer
arithmeLc
to
conveniently
access
arrays
19
Changing
a
Pointer
Argument?
• What
if
want
funcLon
to
change
a
pointer?
• What
gets
printed?
void inc_ptr(int *p)! *q = 50!
{ p = p + 1; }! A!q!
!
int A[3] = {50, 60, 70};!
int *q = A;!
inc_ptr( q);! 50! 60! 70!
printf(“*q = %d\n”, *q);!
Pointer
to
a
Pointer
• SoluLon!
Pass
a
pointer
to
a
pointer,
declared
as
**h!
• Now
what
gets
printed?
void inc_ptr(int **h)! *q = 60!
{ *h = *h + 1; }! A!q! q!
!
int A[3] = {50, 60, 70};!
int *q = A;!
inc_ptr(&q);! 50! 60! 70!
printf(“*q = %d\n”, *q);!
C
Arrays
are
Very
PrimiLve
• An
array
in
C
does
not
know
its
own
length,
and
its
bounds
are
not
checked!
– Consequence:
We
can
accidentally
access
off
the
end
of
an
array
– Consequence:
We
must
pass
the
array
and
its
size
to
any
procedure
that
is
going
to
manipulate
it
• SegmentaLon
faults
and
bus
errors:
– These
are
VERY
difficult
to
find;
be
careful!
(You’ll
learn
how
to
debug
these
in
lab)
22
Use
Defined
Constants
• Array
size
n;
want
to
access
from
0
to
n-‐1,
so
you
should
use
counter
AND
uLlize
a
variable
for
declaraLon
&
incrementaLon
– Bad
pa>ern
int i, ar[10];
for(i = 0; i < 10; i++){ ... }
– Be>er
pa>ern
const int ARRAY_SIZE = 10
int i, a[ARRAY_SIZE];
for(i = 0; i < ARRAY_SIZE; i++){ ... }
• Accessing
elements:
ar[num]
• SINGLE
SOURCE
OF
TRUTH
– You’re
uLlizing
indirecLon
and
avoiding
maintaining
two
copies
of
the
number
10
– DRY:
“Don’t
Repeat
Yourself”
23
PoinLng
to
Different
Size
Objects
• Modern
machines
are
“byte-‐addressable”
– Hardware’s
memory
composed
of
8-‐bit
storage
cells,
each
has
a
unique
address
• A
C
pointer
is
just
abstracted
memory
address
• Type
declaraLon
tells
compiler
how
many
bytes
to
fetch
on
each
access
through
pointer
– E.g.,
32-‐bit
integer
stored
in
4
consecuLve
8-‐bit
bytes
short *y! int *x! char *z!
59
58
57
56
55
54
53
52
51
50
49
48
47
46
45
44
43
42
Byte
address
16-‐bit
short
stored
32-‐bit
integer
8-‐bit
character
in
two
bytes
stored
in
four
bytes
stored
in
one
byte
24
sizeof()
operator
• sizeof(type)
returns
number
of
bytes
in
object
– But
number
of
bits
in
a
byte
is
not
standardized
• In
olden
Lmes,
when
dragons
roamed
the
earth,
bytes
could
be
5,
6,
7,
9
bits
long
• By
definiLon,
sizeof(char)==1
• Can
take
sizeof(arr),
or
sizeof(struc>ype)
• We’ll
see
more
of
sizeof
when
we
look
at
dynamic
memory
management
25
Pointer
ArithmeLc
pointer
+
number
pointer
–
number
e.g.,
pointer
+ 1
adds
1
something
to
a
pointer
char *p; int *p;
char a; int a;
char b; int b;
p = &a; In
each,
p
now
points
to
b
p = &a;
p += 1; (Assuming
compiler
doesn’t
p += 1;
reorder
variables
in
memory.
Never
code
like
this!!!!)
Adds
1*sizeof(char) Adds
1*sizeof(int)
to
the
memory
address
to
the
memory
address
Pointer
arithme)c
should
be
used
cau)ously
26
Arrays
and
Pointers
Passing arrays:
Must explicitly
Really int *array pass the size
•
Array
≈
pointer
to
the
iniLal
(0th)
array
int
element
foo(int array[],
unsigned int size)
{
a[i] ≡ *(a+i) … array[size - 1] …
}
•
An
array
is
passed
to
a
funcLon
as
a
pointer
– The
array
size
is
lost!
int
main(void)
{
•
Usually
bad
style
to
interchange
arrays
and
int a[10], b[5];
pointers
… foo(a, 10)… foo(b, 5) …
– Avoid
pointer
arithmeLc!
}
27
Arrays
and
Pointers
int
foo(int array[],
unsigned int size)
{
… What
does
this
print?
8
printf(“%d\n”, sizeof(array));
...
because
array
is
really
}
a
pointer
(and
a
pointer
is
architecture
dependent,
but
int
likely
to
be
8
on
modern
main(void) machines!)
{
int a[10], b[5];
… foo(a, 10)… foo(b, 5) … What
does
this
print?
40
printf(“%d\n”, sizeof(a));
}
28
Arrays
and
Pointers
int i; int *p;
int array[10]; int array[10];
for (i = 0; i < 10; i++) for (p = array; p < &array[10]; p++)
{ {
array[i] = …; *p = …;
} }
These
code
sequences
have
the
same
effect!
29
Clickers/Peer
InstrucLon
Time
int x[5] = { 2, 4, 6, 8, 10 };!
int *p = x;!
int **pp = &p;!
(*pp)++;!
(*(*pp))++;!
printf("%d\n", *p);!
Result
is:
A:
2
B:
3
C:
4
D:
5
E:
None
of
the
above
30
In
the
News
(1/23/2015):
Google
Exposing
Apple
Security
Bugs
• Google
security
published
details
of
three
bugs
in
Apple
OS
X
(90
days
ager
privately
noLfying
Apple)
– One
network
stack
problem
fixed
in
Yosemite,
all
in
next
beta
– One
is
dereferencing
a
null
pointer
!
– One
is
zeroing
wrong
part
of
memory
!
• Separately,
Google
announces
it
won’t
patch
WebKit
vulnerability
affecLng
Android
4.3
and
below
(only
about
930
million
acLve
users)
31
Concise
strlen()
int strlen(char *s)
{
char *p = s;
while (*p++)
; /* Null body of while */
return (p – s – 1);
}
What
happens
if
there
is
no
zero
character
at
end
of
string?
32
Point
past
end
of
array?
• Array
size
n;
want
to
access
from
0
to
n-1,
but
test
for
exit
by
comparing
to
address
one
element
past
the
array
int ar[10], *p, *q, sum = 0;
...
p = &ar[0]; q = &ar[10];
while (p != q)
/* sum = sum + *p; p = p + 1; */
sum += *p++;
– Is
this
legal?
• C
defines
that
one
element
past
end
of
array
must
be
a
valid
address,
i.e.,
not
cause
an
error
Valid
Pointer
ArithmeLc
• Add
an
integer
to
a
pointer.
• Subtract
2
pointers
(in
the
same
array)
• Compare
pointers
(<,
<=,
==,
!=,
>,
>=)
• Compare
pointer
to
NULL
(indicates
that
the
pointer
points
to
nothing)
Everything
else
illegal
since
makes
no
sense:
• adding
two
pointers
• mulLplying
pointers
• subtract
pointer
from
integer
Arguments
in
main()!
• To
get
arguments
to
the
main
funcLon,
use:
– int main(int argc, char *argv[])!
• What
does
this
mean?
– argc
contains
the
number
of
strings
on
the
command
line
(the
executable
counts
as
one,
plus
one
for
each
argument).
Here
argc
is
2:
unix%
sort
myFile
– argv
is
a
pointer
to
an
array
containing
the
arguments
as
strings
35
Example!
• foo hello 87!
• argc = 3 /* number arguments */
• argv[0] = "foo",
argv[1] = "hello",
argv[2] = "87"!
– Array
of
pointers
to
strings
36
And
In
Conclusion,
…
• Pointers
are
abstracLon
of
machine
memory
addresses
• Pointer
variables
are
held
in
memory,
and
pointer
values
are
just
numbers
that
can
be
manipulated
by
sogware
• In
C,
close
relaLonship
between
array
names
and
pointers
• Pointers
know
the
type
of
the
object
they
point
to
(except
void
*)
• Pointers
are
powerful
but
potenLally
dangerous
37