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:

  1. Allocate space for a db_entry struct
  2. Allocate space for the strings pointed by the name and the value field of the struct
  3. Copy in the strings to the newly allocated space

For function dbe_free, it should:

  1. Free the memory used by name and value members of the struct
  2. 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:

Finishing the Lab

Once you've finished implementing all the functions:

  1. Test that it works. Make sure ./test pass all test cases.
  2. 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.
  3. Ensure both your names are on all of the files you edited. Both of you should submit a copy of the code on Gradescope.
  4. Upload any files you modified (data.c) to Gradescope