11# C-programming-pre-lab <!-- omit in toc -->
22
3- Pre -lab to get started on compiling and running C programs and using ` valgrind ` to identify
4- memory leaks.
3+ This is a pre -lab to get you started started on compiling and running C programs
4+ and using ` valgrind ` to identify memory leaks.
55
66- [ Background] ( #background )
77 - [ Compiling and running a C program] ( #compiling-and-running-a-c-program )
8+ - [ Compiling and running the tests] ( #compiling-and-running-the-tests )
89 - [ Using valgrind to find memory leaks] ( #using-valgrind-to-find-memory-leaks )
910- [ What to do] ( #what-to-do )
1011
@@ -50,11 +51,11 @@ Assuming you're in the project directory, you can compile
5051this using the command
5152
5253``` bash
53- gcc -g -Wall -o check_whitespace check_whitespace.c
54+ gcc -g -Wall -o check_whitespace main.c check_whitespace.c
5455```
5556
56- ` gcc ` is the GNU C Compiler, which is pretty much the only C compiler
57- people use on Linux boxes these days. The meaning of the flags:
57+ ` gcc ` is the GNU C Compiler, which, along with Clang/LLVM, dominates the
58+ C/C++ compiler space on Linux boxes these days. The meaning of the flags:
5859
5960- ` -g ` tells ` gcc ` to include debugging information in the generated
6061 executable. This is allows, for example, programs like ` valgrind `
@@ -74,13 +75,110 @@ people use on Linux boxes these days. The meaning of the flags:
7475 will write the executable to a file called ` a.out ` for strange
7576 historical reasons.
7677
78+ After the flags, we provide a list of all the ` .c ` files that need to be
79+ compiled and [ linked together] ( https://en.wikipedia.org/wiki/Linker_(computing) )
80+ to form a working executable.
81+
7782Assuming your program compiled correctly (** check the output!** ) then you
7883should be able to run the program like any other executable:
7984
8085``` {bash}
8186./check_whitespace
8287```
8388
89+ ### Compiling and running the tests
90+
91+ This includes an example of using
92+ [ the GoogleTest library] ( https://google.github.io/googletest/ )
93+ for writing unit tests for C and C++ programs. The tests are in
94+ ` check_whitespace_test.cpp ` , which has a ` .cpp ` extension because
95+ tests in GoogleTest are actually C++ (` .cpp ` ) instead of just C.
96+
97+ Below are examples of a few tests in GoogleTests:
98+
99+ ``` c++
100+ TEST (Strip, WhitespaceOnBothEnds) {
101+ ASSERT_STREQ("frog", strip(" frog "));
102+ }
103+
104+ TEST(IsClean, NoWhitespace) {
105+ ASSERT_TRUE(is_clean("University of Minnesota Morris"));
106+ }
107+ ```
108+
109+ The two arguments to `TEST` are arbitrary names. The first is the name of
110+ the _suite_ this test is part of; we just used the name of the function
111+ being tested by this test (`Strip` or `IsClean`). The second is the name
112+ of this particular test, and should hopefully provide some useful information
113+ on what's being tested here.
114+
115+ GoogleTest has quite a few assertions. Here we're using `ASSERT_STREQ`, which
116+ asserts that two strings (`STR`) are equal (`EQ`), and `ASSERT_TRUE`.
117+
118+ To compile this is considerably more complicated because we have to use C++
119+ and we need to include the GoogleTest library:
120+
121+ ```text
122+ g++ -Wall -g -o check_whitespace_test check_whitespace.c check_whitespace_test.cpp -lgtest
123+ ```
124+
125+ Here we're using ` g++ ` instead of ` gcc ` to indicate that we want the C++ compiler.
126+ We've also added the ` -lgtest ` at the end, telling the compiler to include the
127+ ` gtest ` _ library_ (hence the ` -l ` ) when constructing the final executable. Also
128+ note that we're _ not_ including ` main.c ` when we compile the test code;
129+ ` check_whitespace_test.cpp ` contains a ` main() ` function so we _ can't_ include
130+ ` main.c ` (which provides a ` main() ` function), or the system won't know which
131+ one to call.
132+
133+ Assuming your program compiled correctly (again, ** check the output!** ) then you
134+ should be able to run the test code:
135+
136+ ``` {bash}
137+ ./check_whitespace_test
138+ ```
139+
140+ If all the tests pass (and they should initially) you should get something like:
141+
142+ ``` text
143+ $ ./check_whitespace_test
144+ [==========] Running 10 tests from 2 test cases.
145+ [----------] Global test environment set-up.
146+ [----------] 5 tests from strip
147+ [ RUN ] strip.EmptyString
148+ [ OK ] strip.EmptyString (0 ms)
149+ [ RUN ] strip.NoWhitespace
150+ [ OK ] strip.NoWhitespace (0 ms)
151+ [ RUN ] strip.WhitespaceOnFront
152+ [ OK ] strip.WhitespaceOnFront (0 ms)
153+ [ RUN ] strip.WhitespaceOnBack
154+ [ OK ] strip.WhitespaceOnBack (0 ms)
155+ [ RUN ] strip.WhitespaceOnBothEnds
156+ [ OK ] strip.WhitespaceOnBothEnds (0 ms)
157+ [----------] 5 tests from strip (0 ms total)
158+
159+ [----------] 5 tests from is_clean
160+ [ RUN ] is_clean.EmptyString
161+ [ OK ] is_clean.EmptyString (0 ms)
162+ [ RUN ] is_clean.NoWhitespace
163+ [ OK ] is_clean.NoWhitespace (0 ms)
164+ [ RUN ] is_clean.WhitespaceOnFront
165+ [ OK ] is_clean.WhitespaceOnFront (0 ms)
166+ [ RUN ] is_clean.WhitespaceOnBack
167+ [ OK ] is_clean.WhitespaceOnBack (0 ms)
168+ [ RUN ] is_clean.WhitespaceOnBothEnds
169+ [ OK ] is_clean.WhitespaceOnBothEnds (0 ms)
170+ [----------] 5 tests from is_clean (0 ms total)
171+
172+ [----------] Global test environment tear-down
173+ [==========] 10 tests from 2 test cases ran. (0 ms total)
174+ [ PASSED ] 10 tests.
175+ ```
176+
177+ You should make sure you recompile and rerun the tests after you
178+ make changes while fixing the memory leak problems down below. It's
179+ not enough to just fix the memory leaks if you also break the code in
180+ the process, and the tests should help ensure that you're good there.
181+
84182### Using valgrind to find memory leaks
85183
86184One of the more subtle problems with explicit memory management is that
@@ -163,7 +261,7 @@ Note that this tells you where the lost bytes were
163261be * freed* , as that's going to depend on how they're used after they're
164262allocated.
165263
166- There are two types of memory leaks, one of which is frankly easier to
264+ There are two common types of memory leaks, one of which is frankly easier to
167265sort out than the other.
168266
169267The easy ones are where function ` f() ` allocates _ local_ memory (memory
@@ -196,9 +294,11 @@ fix has to be made.
196294
197295## What to do
198296
199- - [ ] Compile the program ` check_whitespace.c `
297+ - [ ] Compile the program ` check_whitespace `
200298 and run ` valgrind ` on it to find any leaks it may have (hint: it has at
201299 least one).
300+ - [ ] Also compile ` check_whitespace_test ` and run ` valgrind ` on the test code, to
301+ find any leaks there (there are several).
202302- [ ] In ` leak_report.md ` describe why the memory errors happen, and how to fix them.
203303- [ ] Actually fix the code.
204304- [ ] Commit, push, etc.
0 commit comments