1 / 33

Joel Winstead cs.virginia/~jaw2u

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.

sammy
Download Presentation

Joel Winstead cs.virginia/~jaw2u

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. Menu • Null Pointers in C • Memory Management in C • Phylogeny Revisited 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; 37 i 7 p q 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); } 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! 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! 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); 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 CS 201J Fall 2002

  9. Example char 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 CS 201J Fall 2002

  10. Correcting the Problem char firstChar( /*@null@*/ char *s) { if (s == NULL) { fprintf(stderr,”s is null in firstChar\n”); exit(EXIT_FAILURE); } else { return *s; } } CS 201J Fall 2002

  11. Another Solution char firstChar( /*@notnull@*/ char *s) { return *s; } CS 201J Fall 2002

  12. Memory Management in C

  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)); 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; } 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); } 0 p i 0 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); } 0 p 1 i 1 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); } 0 p 1 i 3 4 9 CS 201J Fall 2002

  18. Detecting Memory Leaks 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. 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 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 9 81 CS 201J Fall 2002

  21. Releasing Memory Too Soon int f() { int *i = malloc(sizeof(*i)); *i = 42; free(i); printf(“i is %d\n”,*i); } The result is undefined! 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. 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. 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. 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. CS 201J Fall 2002

  26. Annotating Constructors Species Species_new(const char *name, const char *genome) { Species s = malloc(sizeof(*s)); s->name = name; s->genome = genome; return s; } 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; } 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; } 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; } 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 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); 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 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) CS 201J Fall 2002

More Related