Download presentation
Presentation is loading. Please wait.
Published byAntony Boone Modified over 6 years ago
1
CS157: Dynamic Memory Dynamic Memory 11/9/201804/25/06
2
Alternative to fixed memory allocation
Dynamic Memory Allocation Alternative to fixed memory allocation Memory space grows or diminishes during program execution Unnecessary to reserve a fixed amount of memory for a scalar, array, or structure variable in advance Also known as run-time allocation Requests are made for allocation and release of memory space while the program is running Dynamic Memory 11/9/201804/25/06
3
Dynamic Memory Allocation
11/9/201804/25/06
4
malloc - Memory Allocate
Requires #include <stdlib.h> Memory is not cleared Takes one parameter – the size (in bytes) void *malloc(size_t size) Returns a pointer to a piece of memory of given size. If unsuccessful, returns NULL malloc(12) returns a pointer to 12 bytes of memory. malloc(sizeof(int) * 100) returns a pointer to a piece of memory that has enough space for 100 ints Dynamic Memory 11/9/2018
5
sizeof(int) == 4 (assume this, for the moment) int i, a[10], *p;
returns the number of bytes used in memory for a specific datatype or variable. sizeof(int) == 4 (assume this, for the moment) int i, a[10], *p; sizeof(i) == 4 sizeof(a) == 40 sizeof(p) == // (assume that pointers are 4 bytes) sizeof can be used with user defined types as well. Dynamic Memory 11/9/2018
6
If you forget to free p eventually you run out of memory! C?
Malloc Package Free your memory when you’re done! void free(void *p) Returns the block pointed at by p to pool of available memory p must come from a previous call to malloc or realloc or calloc (cannot free from the stack) If you forget to free p eventually you run out of memory! C? Dynamic Memory 11/9/2018
7
void *realloc(void *p, size_t size)
Malloc Package realloc Resizing your memory allocation – you can do it! void *realloc(void *p, size_t size) Changes size of block p and returns pointer to new block. Contents of new block unchanged up to min of old and new size – new memory is uninitialized Dynamic Memory 11/9/2018
8
Example allocations malloc calloc free int *grades;
int numgrades = 15; grades = (int *) malloc( numgrades * sizeof(int)); calloc char *base; size = 10; base = (char *) calloc(size, sizeof (char)); free free( base ); free( grades ); Dynamic Memory 11/9/201804/25/06
9
Example: Dynamically create an array of grades, asking the user how many then prompting user for each grade #include <stdio.h> #include <stdlib.h> int main( ) { int numgrades, i; int *grades; // ptr to array of grades printf( "Enter number of grades to be processed: " ); scanf( "%d", &numgrades ); // get memory for the entire array grades = (int *) malloc( numgrades * sizeof(int)); // make sure the allocation worked if ( grades == NULL ) { printf( "Failed to allocate grades array\n" ); return 1; } for ( i=0; i<numgrades; i++ ) { printf( " Enter a grade: " ); scanf( "%d", &grades[i] ); printf( "An array was created for %d integers\n", numgrades ); printf( "Values stored in array are: \n" ); for ( i=0; i<numgrades; i++ ) printf( " %d\n", grades[i] ); free( grades ); return 0; Dynamic Memory 11/9/201804/25/06
10
Here’s a different approach: honesty!
You don’t really need to cast the result of malloc, calloc, or realloc. In general, you need to cast pointers, if you’re assigning a pointer of one type to another. However, void * is special—it doesn’t need casting. Dynamic Memory 11/9/201804/25/06
11
Example: Dynamically create an array of the alphabet, the # of letters dependent on what the user says #include <stdio.h> #include <stdlib.h> int main() { int i,size; char *base; printf("Enter size of array to create "); scanf("%d",&size); base = calloc(size, sizeof(char)); // calloc: handy for arrays if (base == NULL) { printf("Not enough memory\n"); exit(1); } printf("Array of size %d created OK at address %p\n",size,base); for (i=0;i<size;i++) { if ( i%26 == 0 ) base[i] = 'a'; else base[i] = base[i-1]+1; printf("Array Filled\n" ); if ( i != 0 ) printf( "," ); printf( " %c", base[i] ); printf( "\n" ); free( base ); return 0; cs157> gcc -o dym2 dynMem2.c cs157> dym2 Enter size of array to create 4 Array of size 4 created OK at address 0x601010 Array Filled a, b, c, d cs157> Dynamic Memory 11/9/201804/25/06
12
p = (stack *) malloc(sizeof(stack));
malloc returns a pointer to a piece of memory, but it is of type void*. Generally, we want to use the allocated memory to store some specific type. We need to (well, we can) cast the void* pointer to the type we need. p = (stack *) malloc(sizeof(stack)); Dynamic Memory 11/9/2018
13
and the dreaded Memory Leak
The Effect in Memory and the dreaded Memory Leak Dynamic Memory 11/9/2018
14
Memory is divided into two parts
Stack Heap (Stack is a common structure used in computers and in programming. The basics are the same, but here we are talking about memory management as opposed to programming it in our code) Until now, we have only used the stack: Local Variables Parameters Global Variables Constants Dynamic Memory 11/9/2018
15
Process Memory Image %esp the “brk” ptr memory invisible to user code
kernel virtual memory stack %esp Memory mapped region for shared libraries Allocators request additional heap memory from the operating system using the sbrk function. the “brk” ptr run-time heap (via malloc) uninitialized data (.bss) initialized data (.data) program text (.text) Dynamic Memory 11/9/2018
16
Everything on the stack has a name
The only way to get something on the stack is to declare it before you compile. Things on the stack have preset datatypes. You need to know how many items you want and when you want them before you compile. Things on the stack disappear automatically when they are finished. Dynamic Memory 11/9/2018
17
Nothing on the heap has a name
The only way to get something in the heap is to ask for it after the program is running. Heap items have no preset datatype. You can ask for as much, or as little as you want, whenever you want it. Things allocated on the heap remain in memory until you get rid of them explicitly. Dynamic Memory 11/9/2018
18
The free function allows us to give memory back to the heap.
Memory Leaks When a heap item is allocated, it must be explicitly released by the programmer. It's easy to write code that causes a memory leak because it doesn't free some memory that it allocated, but no longer needs. The free function allows us to give memory back to the heap. Dynamic Memory 11/9/2018
19
free free takes a pointer (which you got from a previous call to malloc) and returns nothing. All it does is give the memory back to the OS, which puts it back on the memory heap. After you free something don’t try to use it again. This is a good way to get segfaults. Dynamic Memory 11/9/2018
20
A Few Details malloc does not initialize the memory it gives you. Its contents are undefined. If you want it initialized, that’s your job. Over-/Under-running a piece of malloced memory has VERY unpredictable consequences! The maximum size of a piece of memory you can malloc is determined by the machine and operating system. Dynamic Memory 11/9/2018
21
Finding Problems The best method is to avoid them in the first place. Never call malloc without calling free. valgrind can be used to find problems with dynamic memory usage. valgrind detects the use of uninitialized memory, read/write outside allocated memory, and memory leaks (unfreed memory). Example output from valgrind: ==2554== ERROR SUMMARY: 50 errors from 5 contexts (suppressed: 5 from 1) ==2554== malloc/free: in use at exit: 80 bytes in 1 blocks. ==2554== malloc/free: 2 allocs, 1 frees, 120 bytes allocated. ==2554== For counts of detected errors, rerun with: -v ==2554== searching for pointers to 1 not-freed blocks. ==2554== checked 63,880 bytes. ==2554== ==2554== LEAK SUMMARY: ==2554== definitely lost: 80 bytes in 1 blocks. ==2554== possibly lost: 0 bytes in 0 blocks. ==2554== still reachable: 0 bytes in 0 blocks. ==2554== suppressed: 0 bytes in 0 blocks. ==2554== Use --leak-check=full to see details of leaked memory. Dynamic Memory 11/9/2018
22
char str[100] = "Hello out there!\n"; char *ptr;
Example char str[100] = "Hello out there!\n"; char *ptr; str Hello out there!\n\0 ptr ? Dynamic Memory 11/9/2018
23
char str[100] = "Hello out there!\n"; char *ptr;
Example char str[100] = "Hello out there!\n"; char *ptr; ptr = malloc(sizeof(char) * (strlen(str)+1)); str Hello out there!\n\0 ptr ?????????????????? Dynamic Memory 11/9/2018
24
char str[100] = "Hello out there!\n"; char *ptr;
Example char str[100] = "Hello out there!\n"; char *ptr; ptr = malloc(sizeof(char) * (strlen(str)+1)); strcpy(ptr,str); str Hello out there!\n\0 ptr Hello out there!\n\0 Dynamic Memory 11/9/2018
25
char str[100] = "Hello out there!\n"; char *ptr;
Example char str[100] = "Hello out there!\n"; char *ptr; ptr = malloc(sizeof(char) * (strlen(str)+1)); strcpy(ptr,str); free(ptr); // Assume that we're done with it, now. str Hello out there!\n\0 ptr Dynamic Memory 11/9/2018
26
string.h: strdup strdup (non-standard, but available everywhere) does exactly what I just did on the previous slide. It will malloc exactly enough space for a string, and copy it into the new memory for you. It’s still your job to free it. ptr = strdup("Hello"); ptr2 = strdup(ptr); Dynamic Memory 11/9/2018
27
Returns a (new) pointer to the resized memory.
realloc Takes two parameters The memory to re-allocate The new size Returns a (new) pointer to the resized memory. If it can, it will give you the same pointer. If not, it will copy your old data into the new memory. Dynamic Memory 11/9/2018
28
Can be used to grow OR shrink a previously malloced memory region.
realloc Can be used to grow OR shrink a previously malloced memory region. If the 1st parameter (the old memory) is NULL, it behaves exactly like malloc. If the 2nd parameter (the size) is 0, it behaves exactly like free. You should, however, use malloc and free if possible. They make your intent clear. Dynamic Memory 11/9/2018
29
While we are talking about memory…
memcpy(dst, src, len) Copies len bytes from src to dst. dst and src cannot overlap memmove(dst, src, len) dst and src CAN overlap memset(dst,val,len) initializes len bytes of dst to val memset(ptr,0,sizeof(int) * 100); dst = destination src = source len = length Dynamic Memory 11/9/2018
30
Basically each element of the list is a struct.
Linked Lists Linked lists are a VERY common data structure for storing lists of unknown size Basically each element of the list is a struct. It is a struct which contains a pointer to another element of the same type. Dynamic Memory 11/9/2018
31
struct linked_list *next; }; /* A handy alias for a list element */
Linked List of Floats struct linked_list { float val; struct linked_list *next; }; /* A handy alias for a list element */ typedef struct linked_list list; val next Dynamic Memory 11/9/2018
32
list *ptr = malloc(sizeof(list)); ptr->val = 12.6;
Linked Lists list *ptr = malloc(sizeof(list)); ptr->val = 12.6; ptr->next = NULL; ptr val next 12.6 Dynamic Memory 11/9/2018
33
list *ptr = malloc(sizeof(list)); ptr->val = 12.6;
Linked Lists list *ptr = malloc(sizeof(list)); ptr->val = 12.6; ptr->next = malloc(sizeof(list)); ptr->next->val = 18.5; ptr->next->next = NULL; ptr val next val next 12.6 18.5 Dynamic Memory 11/9/2018
34
Linked Lists Usually the pointer pointing to the beginning of the list is referred to as the “head pointer” val next next head 12.6 val 18.5 val next next 44.7 val 1.6 val next next 18.9 val 0.25 Dynamic Memory 11/9/2018
35
Linked Lists Sometimes, there is a pointer to the last element in the list, also. It is usually called the “tail pointer”. It makes it easy to find the end of the list. val next val next head 12.6 18.5 tail val next val next 44.7 1.6 val next next 18.9 val 0.25 Dynamic Memory 11/9/2018
36
tail->next = malloc(sizeof(list));
Linked Lists tail->next = malloc(sizeof(list)); val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next next val next 18.9 val 0.25 Dynamic Memory 11/9/2018
37
tail = tail->next; Linked Lists val next 12.6 val next head 18.5
44.7 val next 1.6 val next next val next 18.9 val 0.25 Dynamic Memory 11/9/2018
38
tail->val = 10.9; Linked Lists val next 12.6 val next head 18.5
44.7 1.6 val next next val next 18.9 val 0.25 10.9 Dynamic Memory 11/9/2018
39
tail->next = NULL; Linked Lists val next 12.6 val next head 18.5
44.7 1.6 val next next val next 18.9 val 0.25 10.9 Dynamic Memory 11/9/2018
40
Traversing Linked Lists
list *tmp; tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
41
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
42
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
43
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
44
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
45
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
46
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
47
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
48
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
49
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
50
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
51
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
52
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
53
Traversing Linked Lists
for (tmp=head; tmp!=NULL; tmp=tmp->next) printf("%f\n", tmp->val); tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
54
Inserting into a linked list
Insert a new value after tmp. Yes, after. You need a pointer to the previous element to add something to a linked list. tmp val next 12.6 val next head 18.5 tail val next 44.7 val next 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
55
Inserting into a linked list
newval = malloc(sizeof(list)); val next newval tmp val next val next head 12.6 18.5 tail val next val next 44.7 1.6 val next next val next 18.9 val 0.25 10.9 Dynamic Memory 11/9/2018
56
Inserting into a linked list
newval->val = 17.6; val next newval 17.6 tmp val next next head 12.6 val 18.5 tail val next next 44.7 val 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
57
Inserting into a linked list
newval->next = tmp->next; val next newval 17.6 tmp val next next head 12.6 val 18.5 tail val next next 44.7 val 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
58
Inserting into a linked list
tmp->next = newval; val next newval 17.6 tmp val next next head 12.6 val 18.5 tail val next next 44.7 val 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
59
Inserting into a linked list
Or, to redraw it… newval tmp val next next head 12.6 val 18.5 tail val next val next val next 44.7 1.6 17.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
60
Deleting from a linked list
Delete the element after tmp. Yes, after. You need a pointer to the previous element to remove something from a linked list. tmp val next 12.6 val next head 18.5 tail val next 44.7 val next val next 1.6 17.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
61
Deleting from a linked list
victim = tmp->next; victim tmp val next next head 12.6 val 18.5 tail val next 44.7 val next val next 1.6 17.6 val next 18.9 val next val next 0.25 10.9 Dynamic Memory 11/9/2018
62
Deleting from a linked list
tmp->next = victim->next; victim tmp val next next head 12.6 val 18.5 tail val next 44.7 val next val next 1.6 17.6 val next 18.9 val next val next 0.25 10.9 Dynamic Memory 11/9/2018
63
Deleting from a linked list
free(victim); victim tmp val next val next head 12.6 18.5 tail val next next 44.7 val 1.6 val next val next val next 18.9 0.25 10.9 Dynamic Memory 11/9/2018
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.