Title: Joel%20Winstead
1Lecture 16 Pointers and Memory Management
CS201j Engineering Software University of
Virginia Computer Science
- Joel Winstead
- http//www.cs.virginia.edu/jaw2u
2Menu
- Null Pointers in C
- Memory Management in C
- Phylogeny Revisited
3Pointers in C
- Pointers are similar to object references in Java
- Assigning a pointer has sharing semantics
int i 37 int p malloc(sizeof(int)) int
q q p p 7
37
i
7
p
q
4Null Pointers
- What if a pointer doesnt point to anything?
void main(String argv) Integer i
null System.out.println(i.intValue())
int main(int argc,char argv) int i
NULL printf(i is d\n,i)
5Null Pointers
- What if a pointer doesnt point to anything?
void main(String argv) Integer i
null System.out.println(i.intValue())
int main(int argc,char argv) int i
NULL printf(i is d\n,i)
Exception in thread main java.lang.NullPointerEx
ception at nullref.main(nullref.java7)
Behavior is undefined!
6Following Null Pointers
- The program may crash immediately
- The program may produce corrupted output
- The program may corrupt data somewhere else in
the programs memory - This results in a difficult-to-find bug
- The program could mail itself to everyone in your
address book and cause your computer to
self-destruct - The C standard does not define what should
happen, so absolutely anything is legal!
7Splint Annotations for Pointers
- /_at_notnull_at_/
- A pointer guaranteed not to be null
- /_at_null_at_/
- A pointer that might be null
/_at_null_at_/ FILE fopen(/_at_notnull_at_/ char
filename,char mode)
8Splint Warnings
- Splint reports a warning if
- The program dereferences a /_at_null_at_/ pointer
without checking first - The program assigns a /_at_null_at_/ pointer to a
/_at_notnull_at_/ variable - The program passes a /_at_null_at_/ pointer to a
function expecting a /_at_notnull_at_/ pointer
9Example
- char firstChar( /_at_null_at_/ char s)
- return s
-
- gt splint null.c
- Splint 3.0.1.6
- null.c (in function firstChar)
- null.c311 Dereference of possibly null pointer
s s - null.c135 Storage s may become null
- Finished checking --- 1 code warning found
-
10Correcting the Problem
char firstChar( /_at_null_at_/ char s) if (s
NULL) fprintf(stderr,s is null in
firstChar\n) exit(EXIT_FAILURE)
else return s
11Another Solution
char firstChar( /_at_notnull_at_/ char s)
return s
12Memory Management in C
13malloc
- Memory in C is allocated using the malloc
function - This is similar in some ways to Javas new
operator - We use sizeof to determine how much memory to
allocate
int i malloc(sizeof(int)) char s
malloc(sizeof(char)100) Species s
malloc(sizeof(s))
14Creating Objects in C
Species Species_new(const char name,const char
genome) Species result
malloc(sizeof(result)) result-gtname
name result-gtgenome genome return
result
15Memory Leaks
for (i 0 i lt 10 i) int p
malloc(sizeof(p)) p ii printf(d
squared is d\n,i,p)
0
p
i
0
16Memory Leaks
for (i 0 i lt 10 i) int p
malloc(sizeof(p)) p ii printf(d
squared is d\n,i,p)
0
p
1
i
1
17Memory Leaks
for (i 0 i lt 10 i) int p
malloc(sizeof(p)) p ii printf(d
squared is d\n,i,p)
0
p
1
i
3
4
9
18Detecting Memory Leaks
- for (i 0 i lt 10 i)
- int p malloc(sizeof(p))
- p ii
- printf(d squared is d\n,i,p)
-
- gt splint leak.c
- Splint 3.0.1.6
- leak.c116 Fresh storage p not released before
scope exit - A memory leak has been detected. Storage
allocated locally is not released before the last
reference to it is lost.
19free
- Javas garbage collector automatically reclaims
memory - C has no garbage collector
- We must release memory explicitly using the free
function
20Releasing Memory
for (i 0 i lt 10 i) int p
malloc(sizeof(p)) p ii printf(d
squared is d\n,i,p) free(p)
p
i
9
81
21Releasing Memory Too Soon
int f() int i malloc(sizeof(i))
i 42 free(i) printf(i is
d\n,i)
The result is undefined!
22Avoiding Memory Leaks
- Whenever we allocate memory, there is a
responsibility to release it - We can specify what part of the code has this
responsibility by using annotations. - Code that uses an /_at_only_at_/ pointer must free
the storage, or pass the responsibility somewhere
else - If an /_at_only_at_/ pointer is lost of goes out of
scope, Splint warns of a possible memory leak.
23Why does Splint detect the error?
- for (i 0 i lt 10 i)
- int p malloc(sizeof(p))
- p ii
- printf(d squared is d\n,i,p)
-
- gt splint leak.c
- Splint 3.0.1.6
- leak.c116 Fresh storage p not released before
scope exit - A memory leak has been detected. Storage
allocated locally is not released before the last
reference to it is lost.
24Annotating Functions
- We can annotate functions to indicate how they
delegate the responsibility to release memory - /_at_only_at_/ /_at_null_at_/ void malloc(size_t
bytes) - void free(void ptr)
- With these annotations, Splint knows
- Any call to malloc might return NULL
- The caller of malloc is responsible for releasing
the allocated memory.
25Annotating Functions
- We can annotate functions to indicate how they
delegate the responsibility to release memory - /_at_only_at_/ /_at_null_at_/ void malloc(size_t
bytes) - void free(/_at_only_at_/ void ptr)
- With these annotations, Splint knows
- Any call to malloc might return NULL
- The caller of malloc is responsible for releasing
the allocated memory. - free will take responsibility for releasing an
/_at_only_at_/ pointer.
26Annotating Constructors
Species Species_new(const char name,
const char genome)
Species s malloc(sizeof(s)) s-gtname
name s-gtgenome genome return s
27Annotating Constructors
/_at_only_at_/ Species Species_new(const char name,
const char genome) Species s
malloc(sizeof(s)) s-gtname name
s-gtgenome genome return s
28Annotating Constructors
/_at_only_at_/ Species Species_new(const char name,
const char genome) Species s
malloc(sizeof(s)) if (s NULL)
fprintf(stderr,Out of memory in
Species_new.\n) exit(EXIT_FAILURE)
s-gtname name s-gtgenome genome
return s
29Annotating Constructors
/_at_only_at_/ Species Species_new(/_at_only_at_/ const
char name,
/_at_only_at_/ const char genome)
Species s malloc(sizeof(s)) if
(s NULL) fprintf(stderr,Out of memory in
Species_new.\n) exit(EXIT_FAILURE)
s-gtname name s-gtgenome genome
return s
30Dependent and Owned
- Sometimes we need to have more than one pointer
to the same object - However, we want to be able to check that the
object is released - Why cant we use /_at_only_at_/ in this situation?
- /_at_owned_at_/ references indicate an obligation to
release the memory before the reference is lost - /_at_dependent_at_/ references refer to objects that
are /_at_owned_at_/ by some other pointer
31Use of Dependent
void SpeciesSet_insert(SpeciesSet set,
/_at_dependent_at_/ Species species)
- SpeciesSet holds references to Species objects
- We might want to put a single Species object into
more than one SpeciesSet - Therefore, SpeciesSet cannot take responsibility
for releasing the Species object - Some other /_at_owned_at_/ reference must take
responsibility for releasing the Species object
32PS6 Phylogeny Revisited
- We have rewritten the Phylogeny program from
Problem Set 4 in C - The C version of the program has several errors
- Null pointer dereferences
- Memory leaks
- Abstraction violations
- Your job is to use Splint annotations to find and
fix them
33Charge
- The C compiler does not check for null pointer
dereferences or memory leaks - Splint can catch many of these errors if the
program is annotated correctly - PS5 Due Today
- PS6 Use C and Splint (Phylogeny Revisited)