Memory Allocation Professor Jennifer Rexford COS 217 1


































![Printing Chars in Reverse Order #define MAXCHAR 1000 int main(void) { char a[MAXCHAR]; int Printing Chars in Reverse Order #define MAXCHAR 1000 int main(void) { char a[MAXCHAR]; int](https://slidetodoc.com/presentation_image_h/d36cb5fb79ce5a07932fb6b6bab21bd8/image-35.jpg)





- Slides: 40
Memory Allocation Professor Jennifer Rexford COS 217 1
Goals for Today’s Lecture • Behind the scenes of running a program o Code, executable, and process o Main memory vs. virtual memory • Memory layout for UNIX processes, and relationship to C o o o 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 o malloc: allocate memory from the heap o free: deallocate memory from the heap 2
Code vs. Executable vs. Process • C source code o C statements organized into functions o Stored as a collection of files (. c and. h) • Executable module o Binary image generated by compiler o Stored as a file (e. g. , a. out) • Process o Instance of a program that is executing – With its own address space in memory – With its own id and execution state o Managed by the operating system C source code compiling executable running process 3
Main Memory on a Computer • What is main memory? o Storage for variables, data, code, etc. o May be shared among many processes Network CPU Memory Audio Data Bus Disk Video 4
Virtual Memory for a Process • What is virtual memory? o Contiguous addressable memory space for a single process o May be swapped into physical memory from disk in pages o Let’s you pretend each process has its own contiguous memory 0 Network Virtual Address Space Data Bus CPU 32 Audio 32 Memory Disk Video 0 xffff 5
What to Store: Code and Constants • Executable code and constant data o Program binary, and any shared libraries it loads o Necessary for OS to read the commands 0 • OS knows everything in advance Text o Knows amount of space needed o Knows the contents of the memory • Known as the “text” segment • Note: Some systems (e. g. , hats) store some constants in “rodata” section 0 xffff 6
What to Store: “Static” Data • Variables that exist for the entire program o Global variables, and “static” local variables o Amount of space required is known in advance 0 • Data: initialized in the code o Initial value specified by the programmer – E. g. , “int x = 97; ” o Memory is initialized with this value Text Data BSS • BSS: not initialized in the code o Initial value not specified – E. g. , “int x; ” o All memory initialized to 0 (on most OS’s) o BSS stands for “Block Started by Symbol” 0 xffff 7
What to Store: Dynamic Memory • Memory allocated while program is running o E. g. , allocated using the malloc() function – And deallocated using the free() function • OS knows nothing in advance 0 o Doesn’t know the amount of space o Doesn’t know the contents • So, need to allow room to grow Text Data BSS Heap o Known as the “heap” o Detailed example in a few slides o More in programming assignment #4 0 xffff 8
What to Store: Temporary Variables • Temporary memory during lifetime of a function or block o Storage for function parameters and local variables • Need to support nested function calls o One function calls another, and so on o Store the variables of calling function o Know where to return when done 0 • So, must allow room to grow o Known as the “stack” o Push on the stack as new function is called o Pop off the stack as the function ends Text Data BSS Heap • Detailed example later on Stack 0 xffff 9
Memory Layout: Summary • Text: code, constant data • Data: initialized global & static variables • BSS: uninitialized global & static variables 0 • Heap: dynamic memory • Stack: local variables Text Data BSS Heap Stack 0 xffff 10
Memory Layout Example char* string = “hello”; int i. Size; char* f(void) { char* p; i. Size = 8; p = malloc(i. Size); return p; } Text Data BSS Heap Stack 11
Memory Layout Example: Text char* string = “hello”; int i. Size; char* f(void) { char* p; i. Size = 8; p = malloc(i. Size); return p; } Text Data BSS Heap Stack 12
Memory Layout Example: Data char* string = “hello”; int i. Size; char* f(void) { char* p; i. Size = 8; p = malloc(i. Size); return p; } Text Data BSS Heap Stack 13
Memory Layout Example: BSS char* string = “hello”; int i. Size; char* f(void) { char* p; i. Size = 8; p = malloc(i. Size); return p; } Text Data BSS Heap Stack 14
Memory Layout Example: Heap char* string = “hello”; int i. Size; char* f(void) { char* p; i. Size = 8; p = malloc(i. Size); return p; } Text Data BSS Heap Stack 15
Memory Layout Example: Stack char* string = “hello”; int i. Size; char* f(void) { char* p; i. Size = 8; p = malloc(i. Size); return p; } Text Data BSS Heap Stack 16
Memory Allocation &Deallocation • How, and when, is memory allocated? o Global and static variables: program startup o Local variables: function call o Dynamic memory: malloc() • How is memory deallocated? o Global and static variables: program finish o Local variables: function return o Dynamic memory: free() Text Data BSS Heap • All memory deallocated when program ends o It is good style to free allocated memory anyway Stack 17
Memory Allocation Example char* string = “hello”; int i. Size; char* f(void) { char* p; i. Size = 8; p = malloc(i. Size); return p; } Data: “hello” at startup BSS: 0 at startup Stack: at function call Heap: 8 bytes at malloc 18
Memory Deallocation Example char* string = “hello”; int i. Size; char* f(void) { char* p; i. Size = 8; p = malloc(i. Size); return p; } Available till termination Deallocate on return from f Deallocate on free() 19
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] = ’ ’; • 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 20
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); malloc(3); malloc(1); malloc(4); malloc(6); malloc(2); p 1 Heap Text Data } BSS Heap Stack 0 xffff 21
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); malloc(3); malloc(1); malloc(4); malloc(6); malloc(2); p 1 p 2 Heap Text Data } BSS Heap Stack 0 xffff 22
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); malloc(3); malloc(1); malloc(4); malloc(6); malloc(2); p 1 p 2 p 3 Heap Text Data } BSS Heap Stack 0 xffff 23
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); malloc(3); malloc(1); malloc(4); malloc(6); malloc(2); p 1 p 2 p 3 Heap Text Data } BSS Heap Stack 0 xffff 24
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); p 1 malloc(3); malloc(1); malloc(4); p 2 p 3 malloc(6); p 4 malloc(2); Heap Text Data } BSS Heap Stack 0 xffff 25
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); malloc(3); malloc(1); malloc(4); malloc(6); malloc(2); p 1 p 2 p 3 p 4 Heap Text Data } BSS Heap Stack 0 xffff 26
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); p 1 malloc(3); malloc(1); malloc(4); p 5, p 2 p 3 malloc(6); p 4 malloc(2); Heap Text Data } BSS Heap Stack 0 xffff 27
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); p 1 malloc(3); malloc(1); malloc(4); p 5, p 2 p 3 malloc(6); p 4 malloc(2); Heap Text Data } BSS Heap Stack 0 xffff 28
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); p 1 malloc(3); malloc(1); malloc(4); p 5, p 2 p 3 malloc(6); p 4 malloc(2); Heap Text Data } BSS Heap Stack 0 xffff 29
Heap: Dynamic Memory #include <stdlib. h> void *malloc(size_t size); void free(void *ptr); 0 char *p 1 = char *p 2 = char *p 3 = free(p 2); char *p 4 = free(p 3); char *p 5 = free(p 1); free(p 4); free(p 5); p 1 malloc(3); malloc(1); malloc(4); p 5, p 2 p 3 malloc(6); p 4 malloc(2); Heap Text Data } BSS Heap Stack 0 xffff 30
How Do Malloc and Free Work? • Simple answer o Doesn’t matter o Good modularity means you can use it without understanding it • Real answer malloc(s) n = s / sizeof(int) 1 word of overhead n free(p) put p into linked list of free objects n n words of user data 31
Using Malloc and Free • Types o void*: generic pointer to any type (can be converted to other types) o size_t: unsigned integer type returned by sizeof() • void* malloc(size_t size) o Returns a pointer to space of size o … or NULL if the request cannot be satisfied o E. g. , int* x = (int *) malloc(sizeof(int)); • void* calloc(size_t nobj, size_t size) o Returns a pointer to space for array of nobj objects of size o … or NULL if the request cannot be satisfied o Bytes are initialized to 0 • void free(void* p) o Deallocate the space pointed to by the pointer p o Pointer p must be pointer to space previously allocated o Do nothing if p is NULL 32
Using realloc and (never) alloca • void* realloc(void* ptr, size_t size) o “Grows” the allocated buffer o Moves/copies the data if old space insufficient o … or NULL if the request cannot be satisfied • void* alloca(size_t size) o o 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 num. Items) { int items[num. Items]; int *items = alloca(num. Items * sizeof(int)); } 33
Examples Motivating. Realloc() • Example programming tasks o Read text consisting of multiple lines (ending in ‘n’) o Print the lines in alphabetical order • Suppose you don’t know the maximum line size in advance o Could pick a maximum line size in advance o E. g. , #define MAXCHAR 200 o But, what if you need to read and store a longer line? • And you don’t know the number of lines in advance o Could pick a maximum number of lines in advance o E. g. , #define MAXLINE 10000 o But, what if the input has more lines than this? • Better to (re)allocate more memory as you go along 34
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'); } 35
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); 36
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(); … } 37
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(); … } 38
Debugging Malloc Problems • Symptom: “random” failures, especially on call return o Corrupted the stack frame return info • Symptom: calls to malloc/free fail o Corrupted the malloc bookkeeping data • Symptom: program magically works if printf inserted o Corrupted storage space in stack frame • “Debugging” mallocs exist o Doing “man malloc” on Linux reveals MALLOC_CHECK_ o Searching “debug malloc” yields dmalloc, other libraries o Larger problems: valgrind, electric fence, etc. 39
Summary • Five types of memory for variables o o o 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 o Allocation: space allocated o Initialization: initial value, if any o Deallocation: space reclaimed • Understanding memory allocation is important o Make efficient use of memory o Avoid “memory leaks” from dangling pointers 40








































