CSPP 50101 - Lab 10

Lab 10 is due: Saturday, September 3 at 11:59pm

In today's lab:

Getting Started

Files for this lab can be found at: /stage/classes/archive/2011/summer/50101-1/lab/lab10/src

To complete this lab you should be familiar with these topics:

Building a Growable Array Data Structure

In this lab you will build a growable array data structure, and then write a program that uses your data structure. Your growable array will differ from primitive C arrays in two main ways:

As with primitive C arrays, a growable array of size S has valid indices 0 through (S - 1). So, if the end-user sets a value at an index greater than or equal to S, the array will "grow" to fit the new data.

Header file garray.h contains this structure definition to represent an instance of a growable array:

typedef struct garray_s {
  int sz;      /* size of data buffer */
  int * data;  /* data buffer */
} GArray;
You are given a simple file, garray_example.c that shows how a GArray may be used:
 
  /* Initialize an array of size 8 */
  GArray * ga = init(8);
 
  /* set value at index 3 to 42 */
  if ( set_val(ga,3,42) == GA_ERR )
    printf("Call to set_val() failed\n");
 
  ...
 
  /* grow array - set value at index 15 */
  if ( set_val(ga,15,42) == GA_ERR )
    printf("Call to set_val() failed\n");
 

The array should grow to be exactly the size needed to store the new item. So if the current size is 16, and the user sets a value at index 20, then the array will grow to size 21 (with valid indices 0 through 20).

An alternative approach would be to always grow the array by some factor, for example to double the size of the array whenever it must be resized. So in the above example, the array of size 16 would grow to size 32, even though space for only 21 integers is immediately necessary. Doubling the size of the array has the advantage of minimizing the number of times that the array buffer needs to be resized. However, for this lab we will only grow the array to the exact size needed to keep the problem simple.

realloc and dynamic memory allocation

You must use dynamic memory allocation to implement this data structure; remember to use the sizeof operator when you allocate storage for structures and arrays of integers.

You will want to use the function realloc in stdlib.h when you need to grow your growable array. realloc resizes a block of memory that has already been dynamically allocated. The above link describes realloc.

You should check the return type of malloc() and realloc() in your code.

As described below, functions init(), set_value(), and increment() should return an error code if memory allocation fails.

Exercise 1 - Implementing and testing the growable array

The following functions for the GArray interface are declared in the file garray.h: The first function init() is already implemented in garray.c. The file ga_test.c also contains a test of the function init(). Your task for this exercise is to implement the remaining five functions, and add test cases to ga_test.c for each function.

Consider multiple cases when testing each function. For example, you may want to test function ga_size() both before and after an GArray has been resized.

When you are finished test program ga_test.c should contain tests for each of the above functions.

Exercise 2 - Using a Growable Array

In this exercise, you will use the growable array to compute frequency counts of a list of integers. Your program should read the list of integers from standard input and then write the number of occurrences of each observed integer value to standard output. The program should only show values with non-zero counts.

You are given program ga_count.c as a staring point. Submit your work in the same file.

You are given the files simple.dat, in1.dat, and in2.dat to test your program. Your results should look something like this:

 
  $ cat simple.dat
  20
  30
  30
  30
  30
  40
  50
  50
  60
  90
  $ ./ga_count < simple.dat
  20: 1
  30: 4
  40: 1
  50: 2
  60: 1
  90: 1

The expected outputs for files in1.dat and in2.dat are in files out1.dat and out2.dat. Recall that you can use the command line tool diff to compare your output with the expected output.

$ ./ga_count <  in1.dat >  myout1.dat
$ diff out1.dat myout1.dat
$
See Lab 3, Exercise 3 for a review of diff.

Submitting your assignment

Lab 10 is due: Saturday, September 3 at 11:59pm

These files will be evaluated for Lab 10: garray.c, ga_test.c, ga_count.c. You may submit other source code and data files with your lab (but remove compiled binary files.)

Also include a simple README file in your lab10 directory with your name, username, and any other comments or questions for the Lab TA.

You will submit this lab with the hwsubmit program.

 
$ hwsubmit cspp50101lab <path to your lab10 directory>

Submit to cspp50101lab, NOT cspp50101.


prepared by Sonjia Waxmonsky