1 / 40

Memory Allocation

Memory Allocation. Professor Jennifer Rexford COS 217. Goals for Today’s Lecture. Behind the scenes of running a program Code, executable, and process Main memory vs. virtual memory Memory layout for UNIX processes, and relationship to C Text: code and constant data

sorcha
Download Presentation

Memory Allocation

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. Memory Allocation Professor Jennifer Rexford COS 217

  2. Goals for Today’s Lecture • Behind the scenes of running a program • Code, executable, and process • Main memory vs. virtual memory • Memory layout for UNIX processes, and relationship to C • Text: code and constant data • Data: initialized global and static variables • BSS: uninitialized global and static variables • Heap: dynamic memory • Stack: local variables • C functions for memory management • malloc: allocate memory from the heap • free: deallocate memory from the heap

  3. C source code compiling executable running process Code vs. Executable vs. Process • C source code • C statements organized into functions • Stored as a collection of files (.c and .h) • Executable module • Binary image generated by compiler • Stored as a file (e.g., a.out) • Process • Instance of a program that is executing • With its own address space in memory • With its own id and execution state • Managed by the operating system

  4. Main Memory on a Computer • What is main memory? • Storage for variables, data, code, etc. • May be shared among many processes Network Audio CPU Data Bus Disk Video Memory

  5. Virtual Memory for a Process • What is virtual memory? • Contiguous addressable memory space for a single process • May be swapped into physical memory from disk in pages • Let’s you pretend each process has its own contiguous memory 0 Network Audio Virtual Address Space CPU Data Bus 32 32 Disk Video Memory 0xffffffff

  6. What to Store: Code and Constants • Executable code and constant data • Program binary, and any shared libraries it loads • Necessary for OS to read the commands • OS knows everything in advance • Knows amount of space needed • Knows the contents of the memory • Known as the “text” segment • Note: Some systems (e.g., hats) store some constants in “rodata” section 0 Text 0xffffffff

  7. What to Store: “Static” Data • Variables that exist for the entire program • Global variables, and “static” local variables • Amount of space required is known in advance • Data: initialized in the code • Initial value specified by the programmer • E.g., “int x = 97;” • Memory is initialized with this value • BSS: not initialized in the code • Initial value not specified • E.g., “int x;” • All memory initialized to 0 (on most OS’s) • BSS stands for “Block Started by Symbol” 0 Text Data BSS 0xffffffff

  8. What to Store: Dynamic Memory • Memory allocated while program is running • E.g., allocated using the malloc() function • And deallocated using the free() function • OS knows nothing in advance • Doesn’t know the amount of space • Doesn’t know the contents • So, need to allow room to grow • Known as the “heap” • Detailed example in a few slides • More in programming assignment #4 0 Text Data BSS Heap 0xffffffff

  9. What to Store: Temporary Variables • Temporary memory during lifetime of a function or block • Storage for function parameters and local variables • Need to support nested function calls • One function calls another, and so on • Store the variables of calling function • Know where to return when done • So, must allow room to grow • Known as the “stack” • Push on the stack as new function is called • Pop off the stack as the function ends • Detailed example later on 0 Text Data BSS Heap Stack 0xffffffff

  10. Memory Layout: Summary • Text: code, constant data • Data: initialized global & static variables • BSS: uninitialized global & static variables • Heap: dynamic memory • Stack: local variables 0 Text Data BSS Heap Stack 0xffffffff

  11. Memory Layout Example char* string = “hello”; int iSize; char* f(void) { char* p; iSize = 8; p = malloc(iSize); return p; } Text Data BSS Heap Stack

  12. Memory Layout Example: Text char* string = “hello”; int iSize; char* f(void) { char* p; iSize = 8; p = malloc(iSize); return p; } Text Data BSS Heap Stack

  13. Memory Layout Example: Data char* string = “hello”; int iSize; char* f(void) { char* p; iSize = 8; p = malloc(iSize); return p; } Text Data BSS Heap Stack

  14. Memory Layout Example: BSS char* string = “hello”; int iSize; char* f(void) { char* p; iSize = 8; p = malloc(iSize); return p; } Text Data BSS Heap Stack

  15. Memory Layout Example: Heap char* string = “hello”; int iSize; char* f(void) { char* p; iSize = 8; p = malloc(iSize); return p; } Text Data BSS Heap Stack

  16. Memory Layout Example: Stack char* string = “hello”; int iSize; char* f(void) { char* p; iSize = 8; p = malloc(iSize); return p; } Text Data BSS Heap Stack

  17. Memory Allocation & Deallocation • How, and when, is memory allocated? • Global and static variables: program startup • Local variables: function call • Dynamic memory: malloc() • How is memory deallocated? • Global and static variables: program finish • Local variables: function return • Dynamic memory: free() • All memory deallocated when program ends • It is good style to free allocated memory anyway Text Data BSS Heap Stack

  18. Memory Allocation Example char* string = “hello”; int iSize; char* f(void) { char* p; iSize = 8; p = malloc(iSize); return p; } Data: “hello” at startup BSS: 0 at startup Stack: at function call Heap: 8 bytes at malloc

  19. Memory Deallocation Example Available till termination char* string = “hello”; int iSize; char* f(void) { char* p; iSize = 8; p = malloc(iSize); return p; } Available till termination Deallocate on return from f Deallocate on free()

  20. Memory Initialization • Local variables have undefined values int count; • Memory allocated by malloc() has undefined values char* p = (char *) malloc(8); • Must explicitly initialize if you want a particular initial value int count = 0; p[0] = ’\0’; • Global and static variables are initialized to 0 by default static int count = 0; is the same as static int count; It is bad style to depend on this

  21. Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data } BSS Heap Stack 0xffffffff

  22. p2 Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data } BSS Heap Stack 0xffffffff

  23. p2 p3 Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data } BSS Heap Stack 0xffffffff

  24. p3 Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data p2 } BSS Heap Stack 0xffffffff

  25. p3 p4 Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data p2 } BSS Heap Stack 0xffffffff

  26. p4 Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data p2 } BSS p3 Heap Stack 0xffffffff

  27. p4 Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data p5, p2 } BSS p3 Heap Stack 0xffffffff

  28. p4 Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data p5, p2 } BSS p3 Heap Stack 0xffffffff

  29. Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data p5, p2 } BSS p3 Heap p4 Stack 0xffffffff

  30. Heap: Dynamic Memory #include <stdlib.h>void *malloc(size_t size);void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); char *p4 = malloc(6); free(p3); char *p5 = malloc(2); free(p1); free(p4); free(p5); Data p5, p2 } BSS p3 Heap p4 Stack 0xffffffff

  31. How Do Malloc and Free Work? • Simple answer • Doesn’t matter • Good modularity means you can use it without understanding it • Real answer malloc(s) n = s / sizeof(int) free(p) put p into linked list of free objects 1 word of overhead n n n words of user data

  32. Using Malloc and Free • Types • void*: generic pointer to any type (can be converted to other types) • size_t: unsigned integer type returned by sizeof() • void* malloc(size_t size) • Returns a pointer to space of size size • … or NULL if the request cannot be satisfied • E.g., int* x = (int *) malloc(sizeof(int)); • void* calloc(size_t nobj, size_t size) • Returns a pointer to space for array of nobj objects of size size • … or NULL if the request cannot be satisfied • Bytes are initialized to 0 • void free(void* p) • Deallocate the space pointed to by the pointer p • Pointer p must be pointer to space previously allocated • Do nothing if p is NULL

  33. Using realloc and (never) alloca • void* realloc(void* ptr, size_t size) • “Grows” the allocated buffer • Moves/copies the data if old space insufficient • … or NULL if the request cannot be satisfied • void* alloca(size_t size) • Not guaranteed to exist (not in any official standard) • Allocates space on local stack frame • Space automatically freed when function exits • Particularly useful for following: int calc(int numItems) { int items[numItems]; int *items = alloca(numItems * sizeof(int)); }

  34. Examples Motivating Realloc() • Example programming tasks • Read text consisting of multiple lines (ending in ‘\n’) • Print the lines in alphabetical order • Suppose you don’t know the maximum line size in advance • Could pick a maximum line size in advance • E.g., #define MAXCHAR 200 • But, what if you need to read and store a longer line? • And you don’t know the number of lines in advance • Could pick a maximum number of lines in advance • E.g., #define MAXLINE 10000 • But, what if the input has more lines than this? • Better to (re)allocate more memory as you go along

  35. Printing Chars in Reverse Order #define MAXCHAR 1000 int main(void) { char a[MAXCHAR]; int i, c; for (i=0; i<MAXCHAR && ((c=getchar()) != EOF); i++) a[i] = c; while (i > 0) putchar(a[--i]); putchar('\n'); }

  36. And Again With Realloc() #define INIT_SIZE 5 int main(void) { char* a; int i, c, size=INIT_SIZE; a = (char *) malloc(size * sizeof(char)); for (i=0; ((c=getchar()) != EOF); i++) { if (i >= size) { size *= 2; a = (char *) realloc(a, size * sizeof(char)); } a[i] = c; } … free(a); }

  37. Avoid Leaking Memory • Memory leaks “lose” references to dynamic memory int f(void) { char* p; p = (char *) malloc(8 * sizeof(char)); … return 0; } int main(void) { f(); … }

  38. Avoid Dangling Pointers • Dangling pointers point to data that’s not there anymore char *f(void) { char p[8]; … return p; } int main(void) { char *res = f(); … }

  39. Debugging Malloc Problems • Symptom: “random” failures, especially on call return • Corrupted the stack frame return info • Symptom: calls to malloc/free fail • Corrupted the malloc bookkeeping data • Symptom: program magically works if printf inserted • Corrupted storage space in stack frame • “Debugging” mallocs exist • Doing “man malloc” on Linux reveals MALLOC_CHECK_ • Searching “debug malloc” yields dmalloc, other libraries • Larger problems: valgrind, electric fence, etc.

  40. Summary • Five types of memory for variables • Text: code, constant data (constant data in rodata on hats) • Data: initialized global & static variables • BSS: uninitialized global & static variables • Heap: dynamic memory • Stack: local variables • Important to understand differences between • Allocation: space allocated • Initialization: initial value, if any • Deallocation: space reclaimed • Understanding memory allocation is important • Make efficient use of memory • Avoid “memory leaks” from dangling pointers

More Related