C/C++ Programming (2021-12-06 - 2021-12-10, 2022-01-24 - 2022-02-04)¶
2021-12-06¶
Pointers, Arrays, and Commandline
Exercise: Fahrenheit Table Using for
Solutions:
2021-12-07¶
2021-12-08¶
Reiterating on Exercise: Character Histogram
while ((c = getchar()) != EOF) { ... }
: assignment has a value (DRY: don’t repeat yourself)Arrays (and everything else) in C are not range checked ⟶ input needs verification
How far can I write past the end of an array? ⟶ out-of-bounds-write.cpp
From the histogram example: what happens if we receive an
iso-8859-1
Umlaut character, say “ö”. That character is sure not within range[0,128)
.From the smaller-scale canary example.
Aside: C has no
bool
datatype (C++ has) ⟶ infinite-loop.cpp
-
Solution: power.c
-
Char array (i.e., string) walkthrough: strings-wtf.cpp
Massacre using
strcpy
… -
Global variables: global-vs-local.cpp
-
Demo code: type-system.cpp
Massacre resulting from mixing signed and unsigned integers …
-
Exercise: Function That Swaps Two Variables
Fix that to actually swap the caller’s variables: swap-nok.cpp
2021-12-09¶
Morning wakeup, talking about what happened, questions
Reiterate on canary and memory errors in general. Security holes, blah, blah. C is the root of all evil.
argv
; that double pointer thing.Compose an array like
argv
manually (argv-manually.cpp)Double pointers, generally
Pointer arithmetic, killing canaries sitting in a row next to an integer
The same can happen to a function’s return address
Useful use of pointers: singly linked list
Continuing with Pointers and Arrays
-
Hack a little
argv
example
Pointer Recap: pointer-recap.cpp
2022-01-24¶
Undefined Behavior¶
Undefined behavior ist commonplace in C. C++ takes long turns to get undefined behavior out of the way. For example:
Array bounds read/write
It is perfectly ok to read and write past the boundaries of an array. At least this is ok for the compiler; occasionally the program will exhibit undefined behavior - for example when you write into variables in the neighborhood. See undefined-behavior.c.
C++ brings data structures like
std::vector
that can do this better. See undefined-behavior-c++.cpp.
Integer overflow bugs are the norm - happily mix signedness and unsignedness, happily mix various integer widths. See overflow-recap.cpp.
Structures (
struct
) recap; struct-recap.cpp, again with an array bounds write.Pointers recap; pointer-recap-recap.cpp.
Functions recap; power-recap.c.
Modularization¶
What’s that separate compilation unit thing? How do we use the C preprocessor? Dogmatically introducing include guards!
See an example (in C, largely) here.
2022-01-25¶
C++ and OO (Classes)¶
Modularization (again)¶
-
Livehacking this:
2022-01-26¶
Modularization: Repeating Important Topics (Quickly)¶
Classes (continued)¶
-
Livehacking:
2022-01-27¶
Good-morning-exercise: Exercise: Access Methods for Members
(See Classes and Objects for
private
and access methods)Solution see here
-
Livehacking
const
in ol’ C: const-c.cppconst
in C++: const-cpp.cpp
Exercise
-
Livehacking: excursion, back to parameter passing
swap()
, revisited using references instead of pointers: parameter-passing.cppUsing
const
withstruct
types: parameter-passing-struct.cpp
Temporaries, by example. See live-hacking/mystring/temporary.cpp.
2022-01-28¶
Standard Template Library: Container Templates¶
Standard Template Library: Basics
Livehacking: pointer arithmetic, using a C array of
struct User
: user-pointerarith.cpp
2022-01-31¶
2022-02-01¶
Algorithms¶
std::copy
; copy.cppstd::find
; find.cppstd::find_if
; find_if.cppstd::sort
; sort.cppstd::binary_search
; binary_search.cpp
Functors¶
Using
std::for_each
; for_each-functor.cppUsing
std::find_if
; find_if-functor.cpp
Operator Overloading¶
Live-hacking: operator-overloading.cpp
Unified Modeling Language (UML)¶
Exercise (Using All From Today)¶
Exercise: Search a User By Lastname (std::find_if)
For those who chose to return a pointer from
UserDB::search_by_lastname()
… this is how to convert aconst_iterator
to a pointer:
2022-02-02¶
Resolve exercise from yesterday
Associative Container: std::map
¶
Functors: overloading
operator()()
Binary function:
bool operator(l, r)
, as required for example by std::sortProblem: calloperator-problem.cpp
Solution: calloperator-solution.cpp
std::sort<>()
, the problem: using a binary function: sort-problem.cppSolution: write a functor class (still not pretty, too much coding): sort-solution.cpp
Introducing Lambda: sort-lambda.cpp
-
Not much in there though ⟶ live hacking
Exceptions, and Exception Handling¶
Livehacking
Original problem: clumsy (but comprehensive) C-style error handling (using a return value to transport the error, and an “output parameter” for the actual result). exceptions.cpp
Only slightly better: using
std::pair<>
to transport both error and result as return value. exception-pair.cppThrowing
std::exception
(and not catching it). exception-exc.cppCatching
std::exception
. exception-handling.cppReplacing
std::exception
with a custom exception. exceptions-custom.cpp
2022-02-03¶
operator<<(std::ostream&)
: how to, using (again)class Point
: live-hacking/ostream-operator.cppExercise: Paint the American Flag Onto Standard Output
One possible solution, american-flag.cpp. Slightly over-engineered, to show how you write your own
operator<<()
.-
Solution alternatives:
Manual, index-based iteration, naively using
string::operator+=()
: reverse-string-naive.cppIn-place modification using
std::reverse<>()
: reverse-string-reverse.cppstd::reverse_copy<>()
: reverse-string-reverse-copy.cpp
Exercise: Sum of Integers Coming From cin
Solution (a history of iteration in C++, to the point where we do not iterate but use std::accumulate<>() instead): sum-ints.cpp
Exit status again: live-hacking/exit-status.cpp
Explaining libraries, and how they are created with CMake: exercises/joerg/userdb/CMakeLists.txt
2022-02-04¶
C++11: A New Language¶
Dynamic Allocation, Smart Pointers¶
Dynamic memory allocation
Multithreading¶
Live hacked:
Basics: thread-basics.cpp
Start parameters: thread-with-start-parameters.cpp
Lost increment (aka “Mother of All Race Conditions”): thread-lost-increment.cpp
Using a mutex (“toilet door lock”): thread-no-lost-increment-mutex.cpp
Same, but encapsulating the racy integer together with a mutex in a class that behaves like an integer: thread-no-lost-increment-mutex-beautiful.cpp
For integers, though, there is a better way to safety - atomics: thread-no-lost-increment-atomic-fast.cpp
2022-02-07: Start of Exercise Week¶
Moving to Linux: WSL2
Install prerequisites
$ sudo apt install cmake build-essential libsqlite3-dev libboost-all-dev libgtk-3-dev
Unit testing framework documentation: Boost Test Library: The Unit Test Framework
class UserDB
is now an interfaceInto the wild …
Requirements not defined in prosaic words anymore: test driven development
Roman going mad: using wxWidgets to build a GUI on top of our user database
…