This is an in-class exercise. An exercise page like this one will contain a brief description but is intended to be supplemented by discussion during our meeting time. Complete the exercise to the best of your ability in the time given. Feel free to talk with other students as you work, and do not be afraid to ask questions if you get stuck. Aim to complete as much as possible during our meeting, and submit on Gradescope to check your solution. You are encouraged to work at home to complete what you do not get through today.
- gain practice creating complex structs
- utilize structs with functions, structs, and arrays, and structs and pointers
- malloc and free
- review scanf/printf
Part 1
Pull the starter code for this exercise from the public repo by taking the following steps:
Pull the starter code for this exercise from the public repo by taking the following steps:
-
Log into an undergraduate cluster computer. Update the course public repo with a
git pull
command. -
Confirm that you can see the template files for today’s exercise by typing
ls exercises/ex13
– you should see files namedmain.c
,soccer.c
,soccer.h
, andMakefile
inside. -
Copy
main.c
,soccer.c
,soccer.h
, andMakefile
from the public class repository (in the*/exercises/ex13/*
directory) to your personal repo’s directory for this exercise.
Part 2
Open soccer.h
with a text editor. In this file you will find headers for three functions. In this part you need to create struct types to contain information about a soccer “Player”; the “Date” shows the date the player was signed into a team and “Stat” stores basic statistics of a player in a game. Note function declarations are already there. You must define the following struct types (Stat
, Date
and Player
are the struct types and bulleted items below each indicate their struct members) before the function headers:
Stat
int
num_of_goals (scored)int
num_of_assistsfloat
pass_accuracyint
min_playedint
num_of_shotsfloat
shot_accuracy
Date
int
dayint
monthint
year
Player
int
ageint
jersey_numberbool
goalkeeperDate *
date (pointer to a Date struct defined on the heap)Stat *
stat (pointer to a Stat struct defined on the heap)
Part 3
Once you are finished defining the struct types in the header file, you may switch to soccer.c
. There are a few functions in this file, namely create_team, create_player, and print_team. All of those are fully implemented. You should review the implementation of these functions to make sure you understand them.
Part 4
Now switch to main.c
. There are a few things you need to do here. First, you should read information from the input using scanf to create a stat structure. Note that this stat struct is dynamically defined on the heap and new_stat points to it. Then, you need to find the player with the latest signed date in the array “team”. If there are multiple players with the same signed date, you would select the one with smallest index in the array. Finally, update the stat of the player at the index you found with new_stat. Once finished, you can produce an executable by running “make” and run the executable by typing ./main. Check if your code works as expected (i.e., the player’s stats with most recent signed date gets updated properly).
Part 5
Note the use of -g
in the make file, which enables debugging. Now, run the program using valgrind:
valgrind --leak-check=full --show-leak-kinds=all ./main
As you can see, we have calls to malloc
in main and soccer.c
, but not enough calls to free
; there is only one call to free
as a helper for you in main.c
. You need to free stat and date structs on the heap for all the players in the team. Read the valgrind output and make modifications to main.c
to fix the errors/memory leaks.