Title: CS157: Dynamic Memory
1CS157 Dynamic Memory
2Dynamic 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
3Dynamic Memory Allocation
4malloc
- malloc - Memory Allocate
- Requires include ltstdlib.hgt
- 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
5sizeof
- returns the number of bytes used in memory for a
specific datatype or variable. - sizeof(int) 4 (assume this, for the
moment) - int i, a10, p
- sizeof(i) 4
- sizeof(a) 40
- sizeof(p) 4 // (assume that pointers
are 4 bytes) - sizeof can be used with user defined types as
well.
6Malloc Package
- Free your memory when youre 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 eventuallyyou run out
of memory!C?
7Malloc 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
8Example allocations
- malloc
- 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 )
9Example Dynamically create an array of grades,
asking the user how many then prompting user for
each grade
- include ltstdio.hgt
- include ltstdlib.hgt
- 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 ( i0 iltnumgrades i )
10Heres a different approach honesty!
- You dont really need to cast the result of
malloc, calloc, or realloc. - In general, you need to cast pointers, if youre
assigning a pointer of one type to another. - However, void is specialit doesnt need
casting.
11- Example Dynamically create an array of the
alphabet, the of letters dependent on what the
user says
include ltstdio.hgt include ltstdlib.hgt 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 (i0iltsizei)
if ( i26 0 )
basei 'a' else
basei basei-11
printf("Array Filled\n" ) for
(i0iltsizei) if ( i !
0 ) printf( "," )
printf( " c", basei )
printf( "\n" ) free( base )
return 0
cs157gt gcc -o dym2 dynMem2.c cs157gt dym2 Enter
size of array to create 4 Array of size 4 created
OK at address 0x601010 Array Filled a, b, c,
d cs157gt
12malloc
- 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))
13- The Effect in Memory
- and the dreaded Memory Leak
14Memory
- 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
15Process Memory Image
memory invisibleto 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)
0
16The Stack
- 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.
17The Heap
- 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.
18Memory 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.
19free
- 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 dont try to use it
again. This is a good way to get segfaults.
20A Few Details
- malloc does not initialize the memory it gives
you. Its contents are undefined. If you want it
initialized, thats 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.
21Finding 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-checkfull to see details of
leaked memory.
22Example
- char str100 "Hello out there!\n"
- char ptr
str
Hello out there!\n\0
ptr
?
23Example
- char str100 "Hello out there!\n"
- char ptr
- ptr malloc(sizeof(char) (strlen(str)1))
str
Hello out there!\n\0
ptr
??????????????????
24Example
- char str100 "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
25Example
- char str100 "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
26string.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. Its
still your job to free it. - ptr strdup("Hello")
- ptr2 strdup(ptr)
27realloc
- 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.
28realloc
- 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.
29While 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)
- Copies len bytes from src to dst.
- 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
30Linked 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.
31Linked List of Floats
- struct linked_list
- float val
- struct linked_list next
-
- / A handy alias for a list element /
- typedef struct linked_list list
next
val
32Linked Lists
- list ptr malloc(sizeof(list))
- ptr-gtval 12.6
- ptr-gtnext NULL
next
val
ptr
12.6
33Linked Lists
- list ptr malloc(sizeof(list))
- ptr-gtval 12.6
- ptr-gtnext malloc(sizeof(list))
- ptr-gtnext-gtval 18.5
- ptr-gtnext-gtnext NULL
next
val
next
val
12.6
18.5
34Linked Lists
- Usually the pointer pointing to the beginning of
the list is referred to as the head pointer
next
val
next
val
12.6
18.5
head
next
val
next
val
44.7
1.6
next
val
next
val
18.9
0.25
35Linked 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.
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
val
next
val
18.9
0.25
36Linked Lists
- tail-gtnext malloc(sizeof(list))
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
18.9
0.25
37Linked Lists
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
18.9
0.25
38Linked Lists
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
39Linked Lists
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
40Traversing Linked Lists
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
41Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
42Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
43Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
44Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
45Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
46Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
47Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
48Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
49Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
50Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
51Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
52Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
53Traversing Linked Lists
- for (tmphead tmp!NULL tmptmp-gtnext)
- printf("f\n", tmp-gtval)
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
54Inserting 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
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
55Inserting into a linked list
- newval malloc(sizeof(list))
next
val
newval
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
56Inserting into a linked list
next
val
newval
17.6
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
57Inserting into a linked list
next
val
newval
17.6
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
58Inserting into a linked list
next
val
newval
17.6
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
val
next
val
10.9
18.9
0.25
59Inserting into a linked list
newval
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
next
val
val
44.7
1.6
17.6
next
next
val
next
val
val
18.9
10.9
0.25
60Deleting 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
next
val
next
val
12.6
head
18.5
tail
next
val
next
next
val
val
44.7
1.6
17.6
next
next
val
next
val
val
18.9
10.9
0.25
61Deleting from a linked list
victim
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
next
val
val
44.7
1.6
17.6
next
next
val
next
val
val
18.9
10.9
0.25
62Deleting from a linked list
victim
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
next
val
val
44.7
1.6
17.6
next
next
val
next
val
val
18.9
10.9
0.25
63Deleting from a linked list
victim
tmp
next
val
next
val
12.6
head
18.5
tail
next
val
next
val
44.7
1.6
next
next
val
next
val
val
18.9
10.9
0.25