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.
This exercise includes a short, graded and required warm-up
in questions.txt (in the starter). It is a set of
conceptual questions about pointers, structs, memory ownership, and
how a multi-file C program is built.
Answer the questions before you start writing code. You will be
graded on correctness. However, you can freely discuss the answers with
other students. Submit your completed questions.txt along with your code.
In this exercise you will build a small Point3d module
in C. You will define a struct type that bundles three integer
coordinates, write a handful of functions that create, transform,
and inspect points, and split the work across three files with a
main that tests everything. The specifics of the type
and each function are described below.
Point3d type
Define a new structured type named
Point3d that groups together three int32_t
fields for the x, y, and z coordinates. Use typedef to give an alias to your struct. When you are done you should be able to declare a point with syntax like
Point3d p = ...;.
Do not use
typedef to create a pointer alias such as
Point3dPtr. While it is acceptable (and common) to typedef a pointer, it will break our autograder for this exercise. Instead, you should write Point3d* explicitly wherever you need a pointer.
Point3d_Allocate
This function takes three int32_t arguments and hands
back a heap-allocated point. It should malloc
room for a single Point3d, store the three arguments
into the x, y, and z fields, and return a pointer to that
allocation. Think carefully about what should happen if the
allocation does not succeed.
Point3d_Scale
This function takes a Point3d* and a single
int32_t value. It should multiply each of the
pointed-to struct's x, y, and z fields by that value, changing the
struct in place, and return nothing. For the sake of the autograder,
do not return a bool here, even though doing so
would be a reasonable design decision.
Point3d_GetOrigin
This function takes no arguments and produces the origin. It should
build a Point3d whose x, y, and z are all zero and
return a copy of that struct (not a pointer).
main
Write a main function that runs at least one
automated test on each of the functions above. Before you
start, read the "Testing" part of the Implementation Notes below
very carefully so that you understand what an automated test means
in this context.
Modularize your work nicely across three files:
Point3d.h should contain the struct definition
and the function declarations related to Point3d.Point3d.c should contain the function
definitions.ex3.c should contain the main that
tests your functions.
While testing, you can compile your program into an executable
called ex3 with a single command. Your code lives in
three files, but only the two .c source files are named
here, since each of them #includes the
Point3d.h header:
$ gcc -Wall -g -std=c17 -o ex3 ex3.c Point3d.c
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, however, ignore any possible integer overflow errors.
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.
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.
Your main counts as testing code for your
Point3d module, and testing code is the only place
where assert() is allowed, though you are not
required to use it.
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.
Make sure to include header guards, where appropriate, and that you place the function block comments in the appropriate place.
Submit the following files by creating an ex3-submit tag in your exercise repo before the assignment deadline. They must be located at the exact paths listed below, including capitalization:
ex3/ex3.cex3/Point3d.hex3/Point3d.cex3/questions.txtFor full credit, your code must:
attu, or CSE home VM)
using the commands in the Compilation
section.gcc and valgrind)..c file with your name(s) and CSE or UW email
address(es).cpplint.py --clint).