Malloc + structs
Goals
- Learn how use structures for data encapsulation
- Practice programming with dynamic memory (i.e., malloc)
- Practice debugging memory errors
- Learn how use structures for data encapsulation
- Practice putting a semicolon (";") after your struct statement :)
Note: The next few assignments will be based on this one.
Overview
Scenario: Your team will soon choose a leader. You will be given a list of names and a separate list of each person's "favorite" person on the team. You must create software that can calculate the new leader.
Warm-up exercises
This assignment includes a warm-up exercise to help you get ready. This accounts for 10% of your score for HW07. Scoring will be relatively light, but the usual base requirements apply.
To get the starter files, type this: 264get hw07
For the warm-up, you will create a struct type for a name (first and last).
Your type will be called struct Name
and it will have two members:
first
(a char*
) and last
(a char*
).
Next, you will create two swap functions:
swap_first_last(…)
swaps the first and last name in a
given struct Name
instance.
swap_names(…)
swaps two struct Name
instances using pass-by-address.
In warmup.c, you must replace every /* TODO */
comment with code. The
only output is as shown. Fill in the rest of the code to make it work.
Doing the assignment
Here is the overview of what you are creating. (Some specifics have been moved to Requirements.)
- team.h
- struct Person type definition with at least two fields: name (string), favorite (the person's favorite)
- struct Team type definition with at least two fields: people (array of
struct Person
objects) and population (number of people on the team) - forward declarations
- team.c
create team(int population, char✶ names[], int✶ favorites)
creates an instance of struct Team with population people. The favorite of the person named names[i] is favorites[i].pick leader(struct Team✶ team)
returns the most popular person, i.e., the person who is the favorite of the greatest number of people.free team(struct Team✶ team)
frees all heap memory referred to by the team (directly or indirectly).
- test_team.c
main(int argc, char✶ argv[])
function tests your functions in team.c.
Note: Type the declarations into your file manually. Do not copy-paste. (You learn more from typing code manually.)
When you are finished, it will look like this.
Requirements
- Your submission must contain each of the following files, as specified:
file contents team.c functions create team(int population, char✶ names[], int✶ favorites)
→ return type: struct TeamReturn astruct Team
object.
•population
is the number of people in the team, and is always ≥1.
•names
is an array of sizepopulation
containing the names of the team members. Each name is at least one character long, plus the null terminator (i.e., not""
).
•favorites
is an array of sizepopulation
containing the indices of each person's favorite, such thatnames[i]
isfavorites[i]
.
• Thestruct Person
objects this creates, and thename
attribute of each will need to be on the heap. (See the Q&A.)
• A person may be their own favorite.
• Callingcreate_team(…)
will result in exactly population + 1 calls tomalloc(…)
.
• Thestruct Team
object this returns will be on the stack, even though thestruct Person
objects, and thename
attributes they refer to, are on the heap.free team(struct Team✶ team)
→ return type: voidFree all heap memory referred to by the team, directly or indirectly, including thestruct Person
objects inside, and thename
attribute of each.pick leader(struct Team✶ team)
→ return type: struct Person✶Return the address of the most popular person, i.e., thestruct Person
that is the favorite of the greatest number of people in the team.
• If there is a tie, pick the one with the smallest index.team.h struct type definitions struct PersonThis should have at least two fields:name
(a string) andfavorite
(address of astruct Person
object). You may have other fields if you wish, but other fields are not required or necessary.struct TeamThis should have at least two fields:people
(array ofstruct Person
objects) andpopulation
(int
, number of people on the team). You may have other fields if you wish, but other fields are not required or necessary.forward declarations forward declarations of all functions in your team.cYou will need at least three (one for each of the functions defined in your team.c, but you may have others if you like. (See Q1.)test_team.c functions main(int argc, char✶ argv[])
→ return type: intTest all of the code in your team.c. Reminder: Do not copy test cases from the screenshot or anywhere else.warmup.c type definitions struct Namefunctions print name(struct Name name)→ return type: voidWe provide this. Do not modify it.main(int argc, char✶ argv[])→ return type: intWe provide this. Do not modify it, except where it says/* TODO */
.swap first last(…)→ return type: voidswap names(…)→ return type: void -
Only the following external header files, functions, and symbols are
allowed in your team.c.
header functions/symbols allowed in… stdbool.h bool
,true
,false
team.c
,test_team.c
,warmup.c
stdio.h fputc
,fputs
,stdout
test_team.c
,warmup.c
printf
test_team.c
stdlib.h malloc
,free
,NULL
team.c
,test_team.c
,warmup.c
EXIT_SUCCESS
,EXIT_FAILURE
,free
test_team.c
,warmup.c
assert.h assert
team.c
,test_team.c
,warmup.c
- Submissions must meet the code quality standards and the policies on homework and academic integrity.
How much work is this?
This assignment is difficult. It won't require a lot of code, but expect to spend some time debugging and understanding the concepts.
Q&A
-
What is a forward declaration?
A forward declaration is just the top line of a function definition, which specifies its signature. Examples can be found in your textbook on page 155 (Figure 4-5) and page 165 (Figure 4-12).
For example, in HW04, if you wanted to put everying in one file, you could do so like this. The forward declarations let the compiler know what is coming, even before it has read the full function definition.
void mintf(int n, int radix, char* prefix); // <--- forward declaration void print_integer(const char* format, ...); // <--- (aka "function declaration") // Test code int main(int argc, char* argv[]) { // […] } void print_integer(const char* format, ...) { // <--- function definition // […] } void mintf(int n, int radix, char* prefix) { // <--- function definition // […] }
-
Why must the
struct Person
objects be on the heap?
You don't know in advance (i.e., at compile time) how many you will need. -
Why must the
name
field of eachstruct Person
be on the heap?
The string that was passed tocreate_team(…)
might not exist later. -
What is the form of the team returned by
create_team(…)
?
The structure created by the example in the screenshot will look like this:
Updates
9/25: Corrected filename test_team.c (not teamtest.c).
9/26: Clarified where person name should reside, and how population==0 should be handled; added diagram; corrected return type of print_name(…)
in warmup.c; moved most specification details to the Requirements table and elaborated on some items.
9/28: NULL and assert(…) are allowed.