CSE 333 Exercise 3
Due: Wednesday, October 14 by 11 AM
Rating: 2 (note)
Each exercise this quarter is rated on a integer scale of 1 – 5, inclusive, with 1 being the "least time-consuming" and 5 being the "most time-consuming".
This difficulty scale is meant as a rough guide for you in predicting the amount of time to set aside for each exercise as you balance the work required for 333 with your other obligations. However, it is necessarily imperfect as everyone's set of circumstances and experiences with the exercises differ. If your experience with an exercise does not align with its rating, that is not a reflection of you or your abilities.
Goals
- Define and use structs with
typedef. - Use
mallocandfreeto manage dynamically-allocated data without memory leaks. - Write some basic automated tests in C.
- Modularize a C program across multiple files.
Problem Description
Your job is to write a C program that does the following:
- Uses
typedefto define a new structured type calledPoint3d, which containsint32_tfields for x, y, and z coordinates.- This means you should be able to refer to the struct with the following syntax:
Point3d p = ...; - For the sake of the autograder, do not use
typedefto define pointers toPoint3dstructs to bePoint3dPtr; instead, usePoint3d*.
- This means you should be able to refer to the struct with the following syntax:
- Defines a function called
Point3d_Allocatethat (1) accepts threeint32_targuments, (2)malloc's space for aPoint3d, (3) assigns the three arguments to the x, y, and z fields, and (4) returns (a pointer to) themalloc'edPoint3d. - Defines a function called
Point3d_Scalethat (1) accepts onePoint3d*and oneint32_tvalue as arguments, (2) scales the x, y, and z fields of the pointed-to struct by the given value, and (3) returns nothing.- For the sake of the autograder, do not return a
bool, even though it would a reasonable design decision to do so.
- For the sake of the autograder, do not return a
- Defines a function called
Point3d_GetOriginthat (1) accepts no arguments, (2) constructs aPoint3dwith x, y, and z equal to zero, and (3) returns a copy of the struct. - Has a
mainfunction that runs at least one automated test on each of your functions. Make sure to read the relevant portion of the Implementation Notes below ("Testing") very carefully to make sure that you understand what this is asking for. - Is modularized nicely across three files:
Point3d.h,Point3d.c, andex3.c.Point3d.hshould contain the struct definition and function declarations related toPoint3d.Point3d.cshould contain the function definitions.ex3.cshould contain themainthat tests your functions.
Implementation Notes
Error Handling & Robustness
As part of this exercise, you will have to make design decisions
about how to handle errors.
Be sure to take some time and reason about what arguments might be
problematic for each function.
Be sure to handle other types of errors, like the case in which
malloc fails.
Whatever decisions you make, be sure to document them appropriately.
- You may ignore any possible integer overflow errors.
Memory Cleanup
Make sure your main frees any memory that was
dynamically allocated, even when handling edge cases.
We will be using valgrind
(valgrind --leak-check=full ./ex3) to check for
memory leaks and other memory issues.
Testing
For the purposes of this exercise, it is enough for you to write code that makes use of all of the functions that you wrote and verifies that the struct members contain the correct values at each step. When an error is encountered during testing, you should immediately return an appropriate status code to indicate failure in addition to printing an error message. This signals an error to the parent process (this is what makes it automated) and is easier to detect than having to manually scan over your program output, especially if you have a lot of tests.
mainis considered testing code for yourPoint3dmodule. Testing code is the only place where the use ofassert()is allowed, though you do not need to use it at all if you don't want to.
Test Suite
We have provided a test suite executable in your GitLab repo that can help you check just the function signatures of your Point3d code (i.e., it does not check code behavior, style, or memory). This test suite is purposely opaque and will not reveal what is failing. You should aim to see the following output:
$ ./test_ex3 Function and typedef checks purposely not revealed (does not check code behavior). 0 failed
Style Focus
General
For the sake of our autograder, make sure that your function and type names match the specifications exactly, including capitalization. You should write comments explaining the behaviour and purpose of the struct and functions you define. Be sure that the comments you write document how errors are handled.
Typedef
This is supposed to make your life easier! Make sure that your syntax is correct and that you're taking advantage of the new alias.
Multiple files
Make sure to include header guards, where appropriate, and that you place the function block comments in the appropriate place.
Submission
Submit the following file(s) by creating an ex3-submit tag in your repo before the assignment deadline. The file(s) should be located in the exact directory listed below, including capitalization:
ex3/ex3.cex3/Point3d.hex3/Point3d.c
For full credit, your code must:
- Compile without errors or warnings on CSE Linux machines
(lab workstations,
attu, or CSE home VM). - Have no runtime errors, memory leaks, or memory errors
(
gccandvalgrind). - Be contained in the three files described above that compile
into an executable with the following commands:
$ gcc -Wall -g -std=c17 -c -o Point3d.o Point3d.c $ gcc -Wall -g -std=c17 -c -o ex3.o ex3.c $ gcc -Wall -g -std=c17 -o ex3 ex3.o Point3d.o
- Have a comment at the top of your
.cfile with your name(s) and CSE or UW email address(es). - Be pretty: the formatting, modularization, variable and
function names, commenting, and so on should be consistent with
class style guidelines.
Additionally, the linter shouldn't have any complaints about your
code (
cpplint.py --clint). - Be robust: your code should deal with hard-to-handle/edge cases and bogus user input (if there are any) gracefully.