logging in or signing up lecture16 Heng Download Post to : URL : Related Presentations : Share Add to Flag Embed Email Send to Blogs and Networks Add to Channel Uploaded from authorPOINTLite Insert YouTube videos in PowerPont slides with aS Desktop Copy embed code: (To copy code, click on the text box) Embed: URL: Thumbnail: WordPress Embed Customize Embed The presentation is successfully added In Your Favorites. Views: 224 Category: Entertainment License: All Rights Reserved Like it (0) Dislike it (0) Added: November 06, 2007 This Presentation is Public Favorites: 1 Presentation Description No description available. Comments Posting comment... Premium member Presentation Transcript Slide1: Joel Winstead http://www.cs.virginia.edu/~jaw2u CS201j: Engineering Software University of Virginia Computer Science Lecture 16: Pointers and Memory Management Menu: Menu Null Pointers in C Memory Management in C Phylogeny RevisitedPointers in C: 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 7 37 Null Pointers: 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); }Null Pointers: 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!Following Null Pointers: 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!Splint Annotations for Pointers: 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);Splint Warnings: 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@*/ pointerExample: 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 Correcting the Problem: 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; } } Another Solution: Another Solution char firstChar( /*@notnull@*/ char *s) { return *s; } Memory Management in C: Memory Management in Cmalloc: 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));Creating Objects in C: 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; }Memory Leaks: 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 Memory Leaks: 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 1Memory Leaks: 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 9Detecting Memory Leaks: 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.free: free Java’s garbage collector automatically reclaims memory C has no garbage collector We must release memory explicitly using the free function Releasing Memory: 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 Releasing Memory Too Soon: 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!Avoiding Memory Leaks: 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.Why does Splint detect the error?: 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.Annotating Functions: 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.Annotating Functions: 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.Annotating Constructors: Annotating Constructors Species Species_new(const char *name, const char *genome) { Species s = malloc(sizeof(*s)); s->name = name; s->genome = genome; return s; }Annotating Constructors: 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; }Annotating Constructors: 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; }Annotating Constructors: 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; }Dependent and Owned: 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 pointerUse of Dependent: 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);PS6: Phylogeny Revisited: 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 themCharge: 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) You do not have the permission to view this presentation. In order to view it, please contact the author of the presentation.
lecture16 Heng Download Post to : URL : Related Presentations : Share Add to Flag Embed Email Send to Blogs and Networks Add to Channel Uploaded from authorPOINTLite Insert YouTube videos in PowerPont slides with aS Desktop Copy embed code: (To copy code, click on the text box) Embed: URL: Thumbnail: WordPress Embed Customize Embed The presentation is successfully added In Your Favorites. Views: 224 Category: Entertainment License: All Rights Reserved Like it (0) Dislike it (0) Added: November 06, 2007 This Presentation is Public Favorites: 1 Presentation Description No description available. Comments Posting comment... Premium member Presentation Transcript Slide1: Joel Winstead http://www.cs.virginia.edu/~jaw2u CS201j: Engineering Software University of Virginia Computer Science Lecture 16: Pointers and Memory Management Menu: Menu Null Pointers in C Memory Management in C Phylogeny RevisitedPointers in C: 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 7 37 Null Pointers: 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); }Null Pointers: 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!Following Null Pointers: 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!Splint Annotations for Pointers: 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);Splint Warnings: 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@*/ pointerExample: 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 Correcting the Problem: 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; } } Another Solution: Another Solution char firstChar( /*@notnull@*/ char *s) { return *s; } Memory Management in C: Memory Management in Cmalloc: 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));Creating Objects in C: 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; }Memory Leaks: 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 Memory Leaks: 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 1Memory Leaks: 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 9Detecting Memory Leaks: 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.free: free Java’s garbage collector automatically reclaims memory C has no garbage collector We must release memory explicitly using the free function Releasing Memory: 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 Releasing Memory Too Soon: 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!Avoiding Memory Leaks: 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.Why does Splint detect the error?: 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.Annotating Functions: 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.Annotating Functions: 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.Annotating Constructors: Annotating Constructors Species Species_new(const char *name, const char *genome) { Species s = malloc(sizeof(*s)); s->name = name; s->genome = genome; return s; }Annotating Constructors: 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; }Annotating Constructors: 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; }Annotating Constructors: 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; }Dependent and Owned: 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 pointerUse of Dependent: 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);PS6: Phylogeny Revisited: 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 themCharge: 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)