Joel Winstead cs.virginia/~jaw2u

33
Joel Winstead http://www.cs.virginia.edu/ ~jaw2u CS201j: Engineering Software University of Virginia Computer Science Lecture 16: Pointers and Memory Management

description

Lecture 16: Pointers and Memory Management. Joel Winstead http://www.cs.virginia.edu/~jaw2u. CS201j: Engineering Software University of Virginia Computer Science. Menu. Null Pointers in C Memory Management in C Phylogeny Revisited. Pointers in C. - PowerPoint PPT Presentation

Transcript of Joel Winstead cs.virginia/~jaw2u

Page 1: Joel Winstead cs.virginia/~jaw2u

Joel Winsteadhttp://www.cs.virginia.edu/~jaw2u

CS201j: Engineering SoftwareUniversity of VirginiaComputer Science

Lecture 16: Pointers and Memory Management

Page 2: Joel Winstead cs.virginia/~jaw2u

Halloween 2002 CS 201J Fall 2002 2

Menu

• Null Pointers in C

• Memory Management in C

• Phylogeny Revisited

Page 3: Joel Winstead cs.virginia/~jaw2u

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

Page 4: Joel Winstead cs.virginia/~jaw2u

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);

}

Page 5: Joel Winstead cs.virginia/~jaw2u

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!

Page 6: Joel Winstead cs.virginia/~jaw2u

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!

Page 7: Joel Winstead cs.virginia/~jaw2u

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);

Page 8: Joel Winstead cs.virginia/~jaw2u

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

Page 9: Joel Winstead cs.virginia/~jaw2u

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

Page 10: Joel Winstead cs.virginia/~jaw2u

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;

}

}

Page 11: Joel Winstead cs.virginia/~jaw2u

Halloween 2002 CS 201J Fall 2002 11

Another Solutionchar firstChar( /*@notnull@*/ char *s) {

return *s;

}

Page 12: Joel Winstead cs.virginia/~jaw2u

Memory Management in C

Page 13: Joel Winstead cs.virginia/~jaw2u

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));

Page 14: Joel Winstead cs.virginia/~jaw2u

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;

}

Page 15: Joel Winstead cs.virginia/~jaw2u

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

Page 16: Joel Winstead cs.virginia/~jaw2u

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

Page 17: Joel Winstead cs.virginia/~jaw2u

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

Page 18: Joel Winstead cs.virginia/~jaw2u

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.

Page 19: Joel Winstead cs.virginia/~jaw2u

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

Page 20: Joel Winstead cs.virginia/~jaw2u

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

Page 21: Joel Winstead cs.virginia/~jaw2u

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!

Page 22: Joel Winstead cs.virginia/~jaw2u

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.

Page 23: Joel Winstead cs.virginia/~jaw2u

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.

Page 24: Joel Winstead cs.virginia/~jaw2u

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.

Page 25: Joel Winstead cs.virginia/~jaw2u

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.

Page 26: Joel Winstead cs.virginia/~jaw2u

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;

}

Page 27: Joel Winstead cs.virginia/~jaw2u

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;

}

Page 28: Joel Winstead cs.virginia/~jaw2u

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;

}

Page 29: Joel Winstead cs.virginia/~jaw2u

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;

}

Page 30: Joel Winstead cs.virginia/~jaw2u

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

Page 31: Joel Winstead cs.virginia/~jaw2u

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);

Page 32: Joel Winstead cs.virginia/~jaw2u

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

Page 33: Joel Winstead cs.virginia/~jaw2u

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)