Lab 5: Managing Memory
In this lab you'll examine how your machine (and your C compiler) allocates and uses memory.
You can complete this lab in PARTNERS (both of you need to submit the code independently). There is no sign-off or question sheet for this lab (you will be graded based on what you submit to Gradescope).
In this lab, you will need to create a simple database from scratch. The
database will store some entries that each includes two attributes, i.e.,
name
and value
. To implement this, we first define a struct db_entry
as
the data type for each data entry, which has two fields char* name
and char*
value
(see the definition in data.h
). In order to make the database dynamic,
which we can add/remove entries on the run (during runtime), we design the
databse to be an array of struct db_entry*
(a pointer type). By doing this, we
don't need to store the complete struct instances in the database. The size of
this array is defined as a global variable (on the top of the data.c
file)
DB_MAX_SIZE = 128
.
The goal of this lab is to implement a series of API calls to operate this database, e.g., create an entry, remove an entry, search an entry, etc.
Part 1: Allocating (dbe_alloc
) and Freeing (dbe_free
)
Allocating the db_entry
struct (defined in data.h
) when you decide the name
and value
strings
at runtime is not simple: you have to allocate space not only for the struct,
but also for the contents of the struct since they're dynamically allocated! In this
next stage, you'll be automating this process.
For the function dbe_alloc
, it should accomplish the requirements:
- Allocate space for a
db_entry
struct - Allocate space for the strings pointed by the
name
and thevalue
field of the struct - Copy in the strings to the newly allocated space
For function dbe_free
, it should:
- Free the memory used by name and value members of the struct
- Free the memory used by the struct
After you finish implementing dbe_alloc
and dbe_free
, these APIs can be used
as the following example shows (no need to write the code, just make sure you
understand it):
struct db_entry* data = dbe_alloc("My Name", "My Value"); dbe_print(data); dbe_free(data);
Read the comments in data.c
for implementation details.
Testing your allocator
When you finish implementing each function (dbe_alloc
and dbe_free
in this case), type
make ./test
to test the correctness of your code. The same procedure should be used for all the following functions. Your goal is to pass all test cases.
Part 2: Completing the remaining functions in data.c
When you run the tests, you will see there's more work to do.
Finish the following other functions in data.c in this order:
do_add_entry
(HINT: the database is an array of nulls that you will slowly fill up from the beginning)db_count_entries
db_remove
do_list_database
(HINT: this is just a loop that usesdbe_print()
on all the entries in the database)db_find_one
do_remove_first_match
Finishing the Lab
Once you've finished implementing all the functions:
- Test that it works. Make sure
./test
pass all test cases. - If your code does not compile and run, you will get a zero on this lab. You may get partial credit for finishing some of the functions, but your code must at minimum compile and run.
- Ensure both your names are on all of the files you edited. Both of you should submit a copy of the code on Gradescope.
- Upload any files you modified (
data.c
) to Gradescope