Lab 5: Managing Memory

In this lab you'll examine how your machine (and your C compiler) allocates and uses memory. You'll do this lab in PARTNERS.

Goals:

  1. Examine some compiled code on the Pi
  2. Run your program in a debugger and trace procedure calls
  3. Create a simple database

Part 1: Start with a couple db_entrys.

// CSSE 132 Lab 5: simple.c
// Names: <put your names here>

#include "data.h"

void main()
{
  // your code here
}

1.1 Using the stack

Once you've got it working, add code to the main function:

  1. Create a new instance of a struct db_entry called stack on the stack, and sets "name" and "value". (HINT: the struct is already declared in data.h, you don't have to declare it again -- just use it.)
  2. Print the entry using dbe_print (see data.h to see the function's declaration). HINT: you have to pass a memory address to dbe_print, not a struct value.

1.2 Debugging your program

Use GDB to examine your program.

  1. Launch gdb: gdbtui ./simple
  2. Set a "breakpoint" to stop at the beginning of main: break main
  3. Run it: run
  4. When it stops, you should see code. If you don't see code, make sure -g is part of your gcc command.
  5. To advance:
    • for the next line in the same function: type next and hit enter.
    • for the next line in any function (step into a function call): type step and hit enter.
  6. To get information about variables: type info locals and hit enter.
  7. To examine an expression, type print foo (foo is the c expression, for example stack.name)

1.3 Using the heap

When you've got the stack-based db_entry printing out properly, make another one using malloc.

  1. Create an additional struct db_entry called heap on the heap.
    HINT: you may need to include "stdlib.h" if you see warnings about "implicit declaration".
  2. Print heap using the same function as above.
  3. Update the struct to set the name and value (HINT: the -> operator is useful)
  4. Don't forget to free it!

Part 2: Allocating and Freeing something more complicated

Allocating the db_entry struct with strings set at runtime is not simple: you have to allocate space not only for the struct, but also for the contents of the structs! In this next stage, you'll be automating this process.

Your allocator, dbe_alloc will:

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

You'll also need to make a de-allocator called dbe_free that does the reverse:

  1. Free the memory used by name and value members of the struct
  2. Free the memory used by the struct

The goal is to make it easy to create and destroy db_entry structs. After you create dbe_alloc and dbe_free, this is what constructing, printing and freeing an entry will resemble:

struct db_entry* data = dbe_alloc("My Name", "My Value");
dbe_print(data);
dbe_free(data);

Add the above three lines of code to your simple.c program. Compile and run your code to see what it does (you should see a segmentation fault). Why does it fail? (To determine why it fails, use gdb to examine the values of data after each of these lines.)

2.1 Implement dbe_alloc and dbe_free

These functions are implemented in the file named data.c. Open that file in an editor and finish the implementations of dbe_alloc and `dbe_free. When you're done, you should see your simple program print something, not quit with a segmentation fault:

My Name => My Value

Some hints:

2.2 Testing your allocator

While running your simple program is a good test, we've provided you with many more unit tests. To run them, use make test to make the test program, then run that program.

When dbe_alloc and dbe_free are complete, you'll see the first test called test_dbe_allocAndFree pass.

Part 3: Completing data.c

When you run the tests, you will see there's more work to do.

Take a look inside lab5.c. You can see how the database is intended to be used. As you make progress on the rest of the lab, you can use this file to test your progress. (You can also run the tests in test.)

Finish the following other functions in data.c:

For information about how these are used, read the main function in lab5.c and also look at the comments in data.c. You should be able to gradually uncomment the code in that file as you complete parts of this lab.

Finishing the Lab

Once you've finished implementing all the functions:

  1. Test that it works. Make the test program, and run it.
  2. Make sure the code in lab5.c runs (whether you've edited it or not).
  3. Ensure both your names are on all the files you edited.
  4. Commit your changes to SVN.