
Memory Management CMPU 334 – Operating Systems Jason Waterman Memory API: malloc() #include <stdlib.h> void* malloc(size_t size) • Allocate a memory region on the heap • Argument • size_t size : size of the memory block (in bytes) • size_t is an unsigned integer type capable of holding the size of any valid memory request • Often used with sizeof(type)operator which returns the size of the argument • Return • Success: a void type pointer to the memory block allocated by malloc • Fail: a null pointer 9/14/21 CMPU 334 -- Operating Systems 2 Memory API: sizeof() • Good coding style to use sizeof in malloc instead of requesting the number of bytes directly • Two types of results of sizeof with variables • The actual size of ‘x’ is known at run-time int *x = malloc(10 * sizeof(int)); printf(“%d\n”, sizeof(x)); 8 • The actual size of ‘x’ is known at compile-time int x[10]; printf(“%d\n”, sizeof(x)); 40 9/14/21 CMPU 334 -- Operating Systems 3 Memory API: free() #include <stdlib.h> void free(void* ptr) • Free a memory region allocated by a call to malloc • Argument • void *ptr : a pointer to a memory block allocated with malloc • Returns • none 9/14/21 CMPU 334 -- Operating Systems 4 Memory Allocating 2KB heap (free) stack int *pi; // local variable pi 16KB Address Space 2KB points to allocated 2KB + 4 allocated 2KB + 8 allocated 2KB + 12 allocated pi = (int *)malloc(sizeof(int)* 4); (free) 2KB pi 16KB Address Space 9/14/21 CMPU 334 -- Operating Systems 5 Memory Freeing 2KB freed 2KB + 4 freed 2KB + 8 freed 2KB + 12 free(pi); freed (free) pi 16KB Address Space 2KB heap (free) stack 2KB(invalid) pi 16KB Address Space 9/14/21 CMPU 334 -- Operating Systems 6 Forgetting To Allocate Memory • Incorrect code char *src = “hello”; //character string constant char *dst; //unallocated strcpy(dst, src); //segfault and die hello\0 heap strcpy(dst, src); (free) unallocated stack *dst *src Address Space 9/14/21 CMPU 334 -- Operating Systems 7 Forgetting To Allocate Memory (Cont.) • Correct code char *src = “hello”; //character string constant char *dst (char *)malloc(strlen(src) + 1 ); // allocated strcpy(dst, src); //work properly hello\0 hello\0 allocated hello\0 strcpy(dst, src); heap heap (free) (free) stack stack *dst *dst *src *src Address Space Address Space 9/14/21 CMPU 334 -- Operating Systems 8 Not Allocating Enough Memory • Incorrect code, but “works” properly char *src = “hello”; //character string constant char *dst (char *)malloc(strlen(src)); // too small strcpy(dst, src); //works “properly” h e strlen 6 bytes l l o \0 ‘\0’ is omitted 5 bytes hello\0 strcpy(dst, src); heap (free) stack *dst *src Address Space 9/14/21 CMPU 334 -- Operating Systems 9 Forgetting to Initialize • Encounter an uninitialized read int *x = (int *)malloc(sizeof(int)); // allocated printf(“*x = %d\n”, *x); // uninitialized memory access allocated value used before with value used (free) before heap heap (free) (free) stack stack x x Address Space Address Space 9/14/21 CMPU 334 -- Operating Systems 10 Memory Leak • A program runs out of memory and eventually dies unused : unused, but not freed allocated unused unused allocated unused heap heapunused heap (free) allocated (free) stack (free) stack *d *c *b *b *a *a *a Address Space Address Space Address Space run out of memory 9/14/21 CMPU 334 -- Operating Systems 11 Dangling Pointer • Freeing memory before it is finished being used free() *b *b unreachable *a *a dangling pointer 2KB 2KB 3KB 3KB 3KB 3KB 4KB freed free(b) 4KB 4KB NULL NULL Heap Heap (free) (free) Stack Stack *b 3KB *b 3KB *a 2KB *a 2KB Address Space Address Space 9/14/21 CMPU 334 -- Operating Systems 12 Double Free • Free memory that was freed already int *x = (int *)malloc(sizeof(int)); // allocated free(x); // free memory once, OK free(x); // free repeatedly, bad 2KB 2KB allocated freed Heap Heap free(x) free(x) Undefined (free) (free) Error Stack Stack 2KB x 2KB(invalid) 16KB 16KB x Address Space Address Space 9/14/21 CMPU 334 -- Operating Systems 13 Other Memory APIs: calloc() #include <stdlib.h> void *calloc(size_t nmemb, size_t size) • Allocate memory on the heap and zeroes it before returning • Arguments • nmemb: number of elements to allocate • size: size of one element • Returns • Success: a void type pointer to the memory block allocated by calloc • Fail: a null pointer 9/14/21 CMPU 334 -- Operating Systems 14 Other Memory APIs: realloc() #include <stdlib.h> void *realloc(void *ptr, size_t size) • Change the size of memory block • A pointer returned by realloc may be either the same as ptr or a new • Argument • void *ptr: Pointer to memory block allocated with malloc, calloc, or realloc • size_t size: New size for the memory block(in bytes) • Return • Success: Void type pointer to the memory block • Fail: Null pointer 9/14/21 CMPU 334 -- Operating Systems 15 System Calls #include <unistd.h> int brk(void *addr) void *sbrk(intptr_t increment); • malloc library call uses brk system call • brk is called to expand the program’s break • break: The addressof the end of the heap in address space • sbrk increases the break by increment • Programmers should never directly call either brk or sbrk 9/14/21 CMPU 334 -- Operating Systems 16 Free space management • How should free space be managed? • Variable-sized requests • How can we minimize fragmentation • Time and space requirements for allocation algorithms 9/14/21 CMPU 334 -- Operating Systems 17 Splitting • Finding a free chunk of memory that can satisfy the request and splitting it into two • When request for memory allocation is smaller than the size of free chunks 30-byte heap: free used free 0 10 20 30 addr:0 addr:20 free list: head len:10 len:10 NULL 9/14/21 CMPU 334 -- Operating Systems 18 Splitting(Cont.) • Two 10-bytes free segment with 1-byte request 30-byte heap: free used free 0 10 20 30 addr:0 addr:20 free list: head len:10 len:10 NULL ��������� �� − ���� ���� ������� 30-byte heap: free used free 0 10 20 21 30 addr:0 addr:21 free list: head len:10 len:9 NULL 9/14/21 CMPU 334 -- Operating Systems 19 Coalescing • If a user requests memory that is bigger than the free chunk size, the list will not find such a free chunk • Coalescing: Merge returning a free chunk with existing chunks into a large single free chunk if addresses of them are nearby addr:10 addr:0 addr:20 head len:10 Len:10 len:10 NULL ���������� ���� ������ addr:0 head len:30 NULL 9/14/21 CMPU 334 -- Operating Systems 20 Tracking The Size oF Allocated Regions • The interface to free(void *ptr) does not take a size parameter • How does the library know the size of memory region that will be back into free list? • Most allocators store extra information in a header block ptr = malloc(20); The header used by malloc library ptr The 20 bytes returned to caller An Allocated Region Plus Header 9/14/21 CMPU 334 -- Operating Systems 21 The Header of Allocated Memory Chunk • The header minimally contains the size of the allocated memory region • The header may also contain • Additional pointers to speed up deallocation • A magic number for integrity checking hptr size: 20 magic: 1234567 typedef struct __header_t { ptr int size; int magic; The 20 bytes } header_t; returned to caller A Simple Header Specific Contents Of The Header 9/14/21 CMPU 334 -- Operating Systems 22 The Header of Allocated Memory Chunk(Cont.) • The size for free region is the size of the header plus the size of the space allocated to the user • If a user request N bytes, the library searches for a free chunk of size N plus the size of the header • Simple pointer arithmetic to find the header pointer void free(void *ptr) { header_t *hptr = (char *)ptr – sizeof(header_t); } 9/14/21 CMPU 334 -- Operating Systems 23 Embedding a Free List • The memory-allocation library initializes the heap and puts the first element of the free list in the free space • The library can’t use malloc() to build a list within itself • Description of a node in the list typedef struct __node_t { int size; struct __node_t *next; } node_t; • Building the heap and creating a free list • Assume the heap is built with mmap() system call // mmap() returns a pointer to a chunk of free space node_t *head = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); head->size = 4096 - sizeof(node_t); head->next = NULL; 9/14/21 CMPU 334 -- Operating Systems 24 A Heap With One Free Chunk // mmap() returns a pointer to a chunk of free space node_t *head = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); head->size = 4096 - sizeof(node_t); head->next = NULL; [virtual address: 16KB] head header: size field size: 4088 next: 0 header: next field(NULL is 0) ■ ■ ■ the rest of the 4KB chunk 9/14/21 CMPU 334 -- Operating Systems 25 Embedding A Free List: Allocation • If a chunk of memory is requested, the library will first find a chunk that is large enough to accommodate the request • The library will • Split the large free chunk into two • One for the request and the remaining free chunk • Shrink the size of free chunk in the list 9/14/21 CMPU 334 -- Operating Systems 26 Embedding A Free List: Allocation(Cont.) • Example: a request for 100 bytes by ptr = malloc(100) • Allocating 108 bytes out of the existing one free chunk • shrinking the one free chunk to 3980(4088 minus 108) A 4KB Heap With One Free Chunk A Heap : After One Allocation head size: 100 size: 4088 magic: 1234567 next: 0 ptr the rest of ■ ■ ■ ■ ■ ■ the 100 bytes now allocated the 4KB chunk head size: 3980 next: 0 ■ ■ ■ the free 3980 byte chunk 9/14/21 CMPU 334 -- Operating Systems 27 Free Space With Chunks
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages36 Page
-
File Size-