CMSC313, Computer Organization & Assembly Language Programming, Fall 2012

Project 6: Polynomials with malloc()

Due: Thursday November 1, 2012, 11:59pm


The objective of this programming project is to practice working with pointers and memory allocation.


Your assignment is to modify the polynomials abstract data type (ADT) from Project 5 so that the coefficient array is dynamically allocated using malloc(). Furthermore, in this project, you must pass pointers to the poly structs for function calls.

The new header file (poly6.h) looks like:

#ifndef _POLY6_H #define _POLY6_H typedef struct { unsigned int deg ; // degree of polynomial int *coeff ; // coeff[i] is coefficient of x^i term } poly ; // return pointer to new poly struct with memory allocated // in coeff array for a degree d polynomial poly *new_poly (unsigned int d) ; // return pointer to new poly struct with coefficients initialized poly *init_poly (unsigned int d, const int coeff[]) ; // Add two polynomials. Return pointer to newly allocated poly struct. poly *add_poly ( const poly *p1, const poly *p2) ; // Subtract two polynomials. Return pointer to newly allocated poly // struct. poly *sub_poly ( const poly *p1, const poly *p2) ; // Multiply two polynomials. Return pointer to newly allocated poly // struct. poly *mul_poly ( const poly *p1, const poly *p2) ; // void compact_poly (poly *p) ; // Pretty print void print_poly (const poly *p) ; // free space and set *pp to NULL void del_poly(poly **pp) ; #endif

Notice that the functions add_poly(), sub_poly() and mul_poly() now return pointers. These functions should return pointers to dynamically allocated poly structs which have dynamically allocated coeff arrays. Two poly structs must never share the same coeff array.

There are two new functions in the ADT that help us create new polynomials: new_poly() and init_poly(). A call to new_poly(d) returns a pointer to a newly allocated poly struct that has a newly allocated coeff array for a degree d polynomial (which requires d+1 entries). A call to init_poly(d, coeff) also returns a pointer to a new degree d polynomial, but init() uses the coeff array parameter to initialize the coeff array of the new polynomial. (Don't confuse the two coeff arrays. One is a formal parameter, the other is a field in the poly struct.)

We also have a new function del_poly(pp) that deallocates the dynamically allocated memory used by a polynomial. We are also excessively paranoid and want to zero out the pointer to this space. Hence the parameter pp is a pointer to a pointer to a poly struct. (We are essentially passing a poly pointer by reference.) For example, we might have:

poly *p ; p = new_poly(3) ; // ... do something ... del_poly(&p) ; // p now points to NULL Notice that in the call to del_poly(), the address of p is the actual parameter. This allows del_poly to make p point to NULL. This prevents us from accidentally using the poly struct that has been freed.

The compact_poly() function is extra credit (see below). If you do not want to pursue extra credit then just have compact_poly() return without doing anything:

void compact_poly (poly *p) { return ; }

Once you have implemented these functions, then you can use polynomials in the main function simply by calling functions like this:

int coeff1[] = {2, -1, 1, -2} ; poly *p1 ; p1 = init_poly(3, coeff1) ; int coeff2[] = {1, 3} ; poly *p2 ; p2 = init_poly(1, coeff2) ; poly *answer ; answer = add_poly(p1, p2) ; print_poly(p1) ; printf(" plus ") ; print_poly(p2) ; printf(" equals ") ; print_poly(answer) ; printf("\n") ; del_poly(&answer) ; The code above should produce output that looks like: -2 x^3 + x^2 - x + 2 plus 3 x + 1 equals -2 x^3 + x^2 + 2 x + 3

Implementation Notes

Extra Credit

For 10% extra credit, implement the compact_poly(p) function. This function reduces the size of the coefficient array in p to just the right size. This function is needed because it is possible to add or subtract two polynomials and have the leading term cancel out. The resulting polynomial can have lower degree than the two original polynomials.

The compact_poly(p) function should find the non-zero term with highest degree stored in *p. If this degree is lower than indicated in p->deg then the function should allocate a new (smaller) coefficient array, copy over the coefficients and free the old coefficient array. The compact_poly() function must also update the deg field. Finally, compact_poly() should handle the special case of the zero polynomial, which should be stored as a degree 0 polynomial with a single coefficient that is 0. (Do not use a NULL pointer to represent the zero polynomial.)

When you have implemented the compact_poly() function, use it in your add_poly(), sub_poly() and mul_poly() functions. For full credit, you must include test cases that demonstrate that your compact_poly() implementation works.

Turning in your program

Use the UNIX submit command on the GL system to turn in your project.

When you are done, use the script Unix command to record yourself running your program.

You should submit 3 files: main6.c, poly6.c and typescript. You should not submit poly6.h since this must be identical to the one distributed. Note: main6.c must have test cases that demonstrate the features of your program. You should not rely on the simple test cases in the original main6.c.

The UNIX command to submit should look like:

submit cs313 proj6 main6.c poly6.c typescript

Last Modified: 25 Oct 2012 11:33:27 EDT by Richard Chang
to Fall 2012 CMSC 313 Homepage