Assignment 12: Hold on to your memories
Due Friday, December 6th, before midnight. Written portion is due December 5th - no late work accepted
The goals for this assignment are:
-
Understand void* types and pointer arithmetic
-
More linked list practice
-
Better understand malloc and free, particularly the use of the free list
Update your repository
Do a fetch upstream to obtain the basecode for this assignment.
Using the command line
-
Open terminal and change your current directory to your assignment repository.
-
Run the command
git fetch upstream
-
Run the command
git merge upstream/master
Your repository should now contain a new folder named A10
.
The fetch
and merge
commands update your repository with any changes from the original.
1. Description
In this assignment, we will implement our own version of malloc and free based on "first-fit" strategy and analyze its behavior.
For this assignment, you should submit both
-
your code, and
-
a written report, due in class
2. Code setup
Your basecode includes the following source files
-
mylloc_list.c
- Malloc/free implementation that implements a free list with first-fit strategy (corresponds tomhysa.c
in reading) -
rand.c
- Utilities for generating random sizes of memory -
sbrk.c
- Utilities for extending the amount of memory allocated to a program -
memstats.c
- A benchmark program -
unit_tests.c
- Unit tests for your malloc/free implementation
This assignment is based on the reading: "My malloc: mylloc and mhysa" by
Johan Montelius, posted to Slack. You should complete the reading and finish the
implementation of mylloc_list.c before starting the assignment.
|
3. mylloc_list
In mylloc_list.c
, implement malloc and free based on the reading.
Recall that the reading steps you through implementing your own malloc/free
based on a free list and a first-fit strategy. This implementation uses a
header to keep track of the memory requested from sbrk
. When we re-use memory
that is freed, we typically will not re-use the entire block of memory. Modify
the implementation from the reading to
-
Extend this header to keep track of both the requested size and the amount of memory currently used in the chunk.
struct chunk {
int size; // size of memory allocated from sbrk
int used; // *NEW*: amount currently in use
struct chunk *next;
};
Use the unit tests included with your assignment to test that your implementation is correct
$ make all
gcc -g -Wall -Wvla -Werror memstats.c mylloc_list.c sbrk.c rand.c -o memstats -lm
gcc -g -Wall -Wvla -Werror unit_tests.c mylloc_list.c sbrk.c rand.c -o unit_tests -lm
$ ./unit_tests
Running tests...
test 1: size 0 returns NULL: PASSED
test 2: flist is NULL to start: PASSED
test 3: flist is empty after first malloc: PASSED
test 4: correct amount allocated: PASSED
test 5: header size correct: PASSED
test 6: header used correct: PASSED
test 7: flist is non-empty after free: PASSED
test 8: flist is empty: PASSED
test9: correct amount allocated: PASSED
test 10: header size correct: PASSED
test 11: header used correct: PASSED
test 12: flist is not empty: PASSED
test 13: current-init correct size: PASSED
test 14: header size correct: PASSED
test 15: header used correct: PASSED
test 16: flist's first node has correct size: PASSED
test 17: flist is non-empty: PASSED
test 18: flist's second node has correct size: PASSED
4. Memory statistics
In memstats.c
, implement the function memstats
to print the following information
-
The total number of memory blocks allocated by malloc, along with
-
The number of total blocks which are currently in-use
-
The number of total blocks which are currently free
-
-
The total amount of memory allocated by malloc, along with
-
The total amount of memory currently in-use
-
The total amount of memory currently free
-
-
The amount of underutilised memory as a percentage. This is the percent of memory that has been allocated by
sbrk
but not being used by the application.
For example, your function might produce the following output
Total blocks: 8 Free blocks: 6 Used blocks: 2
Total memory allocated: 9665 Free memory: 4427 Used memory: 5238
Underutilized memory: 0.48
You are given code to simulate many random allocations and frees. After implementing your function, you should get the following output.
$ ./memstats
Starting test..
The initial top of the heap is 0x7feffe84d010.
---------------
0
Allocating 452 bytes at index 0
Allocating 1042 bytes at index 4
Allocating 45 bytes at index 1
Freeing index 0
Allocating 68 bytes at index 0
Freeing index 1
Freeing index 0
Allocating 127 bytes at index 3
Allocating 1141 bytes at index 2
Allocating 89 bytes at index 1
The new top of the heap is 0x7feffe84db31.
Increased by 2849 (0xb21) bytes
Total blocks: 5 Free blocks: 1 Used blocks: 4
Total memory allocated: 2769 Free memory: 45 Used memory: 2724
Underutilized memory: 0.12
---------------
1
Freeing index 3
Allocating 47 bytes at index 0
Freeing index 4
Freeing index 1
Freeing index 2
Freeing index 0
Allocating 3426 bytes at index 1
Freeing index 1
Allocating 39 bytes at index 2
Allocating 163 bytes at index 4
The new top of the heap is 0x7feffe84e8a3.
Increased by 3442 (0xd72) bytes
Total blocks: 6 Free blocks: 4 Used blocks: 2
Total memory allocated: 6195 Free memory: 2317 Used memory: 3878
Underutilized memory: 0.95
---------------
2
Allocating 1658 bytes at index 3
Allocating 1812 bytes at index 0
Freeing index 3
Allocating 39 bytes at index 3
Allocating 156 bytes at index 1
Freeing index 3
Freeing index 1
Freeing index 4
Freeing index 2
Allocating 921 bytes at index 1
The new top of the heap is 0x7feffe84f651.
Increased by 3502 (0xdae) bytes
Total blocks: 8 Free blocks: 6 Used blocks: 2
Total memory allocated: 9665 Free memory: 4427 Used memory: 5238
Underutilized memory: 0.48
Time is 4.1e-05
4.1. README (Due in class as a hardcopy)
Read this section and answer the corresponding questions. We will visualize the execution of memstats.c
for Round 1.
When the program starts, we have no buffers allocated and the free list is empty.
After the first 3 allocations, the buffers and free list look as follows:
After the next iteration, we have
After the next iteration, we have
After the next iteration, we have
At the end of round 1, the buffers and free list look as follows
Answer the following questions:
-
Why is the total memory allocated equal to 2769 bytes?
-
If the total memory is equal to 2769 bytes, why did the heap increase by 2849 bytes?
-
Why is the underutilized memory 12%?
-
Draw the buffers and free list after round 1
-
Draw the buffers and free list after round 2
5. Submit your work
Submit both your code (by midnight) and your written questions (due in class Wednesday).
1) Push your code work to github
$ git status
$ git add .
$ git status
$ git commit -m "assignment complete"
$ git status
$ git push
$ git status
6. Grading Rubric
Assignment rubrics
Grades are out of 4 points.
-
(2 points) mylloc_list
-
(0.1 points) style and header comment
-
(1.9 points) passes all tests
-
-
(1 points) memstats
-
(0.1 points) style and header comment
-
(0.9 points) correct output
-
-
(1 points) Readme
valgrind won’t work for this assignment. You do not need to check for memory errors on this assignment. |
Code rubrics
For full credit, your C programs must be feature-complete, robust (e.g. run without memory errors or crashing) and have good style.
-
Some credit lost for missing features or bugs, depending on severity of error
-
-5% for style errors. See the class coding style here.
-
-100% for failure to checkin work to Github
-
-100% for failure to compile on linux using make