Joel Winstead cs.virginia/~jaw2u
description
Transcript of Joel Winstead cs.virginia/~jaw2u
Joel Winsteadhttp://www.cs.virginia.edu/~jaw2u
CS201j: Engineering SoftwareUniversity of VirginiaComputer Science
Lecture 16: Pointers and Memory Management
Halloween 2002 CS 201J Fall 2002 2
Menu
• Null Pointers in C
• Memory Management in C
• Phylogeny Revisited
Halloween 2002 CS 201J Fall 2002 3
Pointers 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;
i
p
q
737
Halloween 2002 CS 201J Fall 2002 4
Null Pointers
• What if a pointer doesn’t 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);
}
Halloween 2002 CS 201J Fall 2002 5
Null Pointers
• What if a pointer doesn’t 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.NullPointerException at nullref.main(nullref.java:7)
Behavior is undefined!
Halloween 2002 CS 201J Fall 2002 6
Following Null Pointers
• The program may crash immediately• The program may produce corrupted output• The program may corrupt data somewhere else
in the program’s 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!
Halloween 2002 CS 201J Fall 2002 7
Splint Annotations for Pointers• /*@notnull@*/
– A pointer guaranteed not to be null
• /*@null@*/– A pointer that might be null
/*@null@*/ FILE * fopen(/*@notnull@*/ char *filename,char *mode);
Halloween 2002 CS 201J Fall 2002 8
Splint Warnings
• Splint reports a warning if:– The program dereferences a /*@null@*/
pointer without checking first– The program assigns a /*@null@*/ pointer to
a /*@notnull@*/ variable– The program passes a /*@null@*/ pointer to a
function expecting a /*@notnull@*/ pointer
Halloween 2002 CS 201J Fall 2002 9
Examplechar firstChar( /*@null@*/ char *s) {
return *s;
}
> splint null.c
Splint 3.0.1.6
null.c: (in function firstChar)
null.c:3:11: Dereference of possibly null pointer s: *s
null.c:1:35: Storage s may become null
Finished checking --- 1 code warning found
Halloween 2002 CS 201J Fall 2002 10
Correcting the Problemchar firstChar( /*@null@*/ char *s) {
if (s == NULL) {
fprintf(stderr,”s is null in firstChar\n”);
exit(EXIT_FAILURE);
} else {
return *s;
}
}
Halloween 2002 CS 201J Fall 2002 11
Another Solutionchar firstChar( /*@notnull@*/ char *s) {
return *s;
}
Memory Management in C
Halloween 2002 CS 201J Fall 2002 13
malloc
• Memory in C is allocated using the malloc function– This is similar in some ways to Java’s 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));
Halloween 2002 CS 201J Fall 2002 14
Creating Objects in C
Species Species_new(const char *name,const char *genome) {
Species result = malloc(sizeof(*result));
result->name = name;
result->genome = genome;
return result;
}
Halloween 2002 CS 201J Fall 2002 15
Memory Leaks
for (i = 0; i < 10; i++) {
int *p = malloc(sizeof(*p));
*p = i*i;
printf(“%d squared is %d\n”,i,*p);
}
p
i 0
0
Halloween 2002 CS 201J Fall 2002 16
Memory Leaks
for (i = 0; i < 10; i++) {
int *p = malloc(sizeof(*p));
*p = i*i;
printf(“%d squared is %d\n”,i,*p);
}
p
i 1
0
1
Halloween 2002 CS 201J Fall 2002 17
Memory Leaks
for (i = 0; i < 10; i++) {
int *p = malloc(sizeof(*p));
*p = i*i;
printf(“%d squared is %d\n”,i,*p);
}
p
i 3
0
1
4
9
Halloween 2002 CS 201J Fall 2002 18
Detecting Memory Leaksfor (i = 0; i < 10; i++) {
int *p = malloc(sizeof(*p));
*p = i*i;
printf(“%d squared is %d\n”,i,*p);
}
> splint leak.c
Splint 3.0.1.6
leak.c:11:6 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.
Halloween 2002 CS 201J Fall 2002 19
free
• Java’s garbage collector automatically reclaims memory
• C has no garbage collector
• We must release memory explicitly using the free function
Halloween 2002 CS 201J Fall 2002 20
Releasing Memory
for (i = 0; i < 10; i++) {
int *p = malloc(sizeof(*p));
*p = i*i;
printf(“%d squared is %d\n”,i,*p);
free(p);
}
p
i 981
Halloween 2002 CS 201J Fall 2002 21
Releasing Memory Too Soonint f() {
int *i = malloc(sizeof(*i));
*i = 42;
free(i);
printf(“i is %d\n”,*i);
}
The result is undefined!
Halloween 2002 CS 201J Fall 2002 22
Avoiding 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 /*@only@*/ pointer must free the storage, or pass the responsibility somewhere else
• If an /*@only@*/ pointer is lost of goes out of scope, Splint warns of a possible memory leak.
Halloween 2002 CS 201J Fall 2002 23
Why does Splint detect the error?for (i = 0; i < 10; i++) {
int *p = malloc(sizeof(*p));
*p = i*i;
printf(“%d squared is %d\n”,i,*p);
}
> splint leak.c
Splint 3.0.1.6
leak.c:11:6 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.
Halloween 2002 CS 201J Fall 2002 24
Annotating Functions
• We can annotate functions to indicate how they delegate the responsibility to release memory:
/*@only@*/ /*@null@*/ 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.
Halloween 2002 CS 201J Fall 2002 25
Annotating Functions
• We can annotate functions to indicate how they delegate the responsibility to release memory:
/*@only@*/ /*@null@*/ void * malloc(size_t bytes); void free(/*@only@*/ 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
/*@only@*/ pointer.
Halloween 2002 CS 201J Fall 2002 26
Annotating ConstructorsSpecies Species_new(const char *name,
const char *genome) {
Species s = malloc(sizeof(*s));
s->name = name;
s->genome = genome;
return s;
}
Halloween 2002 CS 201J Fall 2002 27
Annotating Constructors/*@only@*/ Species Species_new(const char *name,
const char *genome) {
Species s = malloc(sizeof(*s));
s->name = name;
s->genome = genome;
return s;
}
Halloween 2002 CS 201J Fall 2002 28
Annotating Constructors/*@only@*/ 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->name = name;
s->genome = genome;
return s;
}
Halloween 2002 CS 201J Fall 2002 29
Annotating Constructors/*@only@*/ Species Species_new(/*@only@*/ const char *name,
/*@only@*/ const char *genome) {
Species s = malloc(sizeof(*s));
if (s == NULL) {
fprintf(stderr,”Out of memory in Species_new.\n”);
exit(EXIT_FAILURE);
}
s->name = name;
s->genome = genome;
return s;
}
Halloween 2002 CS 201J Fall 2002 30
Dependent 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 can’t we use /*@only@*/ in this situation?
• /*@owned@*/ references indicate an obligation to release the memory before the reference is lost
• /*@dependent@*/ references refer to objects that are /*@owned@*/ by some other pointer
Halloween 2002 CS 201J Fall 2002 31
Use of Dependent
• 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 /*@owned@*/ reference must take
responsibility for releasing the Species object
void SpeciesSet_insert(SpeciesSet set, /*@dependent@*/ Species species);
Halloween 2002 CS 201J Fall 2002 32
PS6: 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
Halloween 2002 CS 201J Fall 2002 33
Charge• 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)