C++ WORKSHOP HANDS-ON
CONTENTS
Exercise 1: memerr.cpp (memory errors)
Execute the following:
make distclean make debug=1 ./bin/memerr
In src/memerr.cpp uncomment DO_ERROR_ADDRESS_SANITIZER, and repeat step 1. Explain the result.
1) Comment out the buffer overflow case, build, run and explain the result.
2) Comment out the use after free case, build, run and explain the result.
3) Comment out the double free case, build, run and explain the result.
In src/memerr.cpp uncomment DO_ERROR_STACK_PROTECTOR, and repeat step 1. Explain the result.
In src/memerr.cpp uncomment DO_ERROR_FORTIFY_SOURCE, and repeat step 1. Explain the result.
Related links:
Exercise 2: auto.cpp (type deduction)
Execute the following:
make distclean make debug=1 ./bin/auto
The unit tests should fail!
Those test cases contain some example with type deduction. Study the examples and replace the
void
cases with the correct type in order to pass the unit test.
Exercise 3: stl.cpp (STL & algorithms)
Execute the following:
make distclean make ./bin/stl
The unit tests should fail! This section is based on STL algorithms and sequences, so a very handy link is: http://en.cppreference.com/w/cpp/algorithm
Fix unit test
geometric
Fill the function
generate_geometric_samples
in order to generate avector
with geometric sequences. Geometric sequence is a sequence of numbers where each term after the first is found by multiplying the previous one by a fixed, non-zero number called the common ratio. For example, the sequence 2, 6, 18, 54, ... is a geometric progression with common ratio 3.Tip: use std::generate
Then fill the function
is_divisible_by
in order to check if all elements of avector
are divisible by some number.Tip: use std::all_of
Fix unit test
remove
Fill the remove criteria in
remove_even_numbers
.[optional] Fix unit test
counting
Implement
count_unique_words
so as to keep a counter for every word met in the string. The function must use a generic map structure.Tip: check http://en.cppreference.com/w/cpp/container/unordered_map
[optional] Fix unit test
timing
Implement the return value of
time_find
.
Exercise 4: move.cpp (filesystem access with move semantics)
Execute the following:
make distclean make ./bin/move ./src/move.cpp
Why is the assertion failing? Correct the issue!
Execute the following:
./bin/move /dev/urandom
To debug the problem, you may use gdb (C-x o to change active Text User Interface window!):
gdb -tui ./bin/move (gdb) run /dev/urandom (gdb) bt (gdb) p *this (gdb) p size_ (gdb) whatis buf_ (gdb) cont (gdb) q
Before correcting the issue, use also AddressSanitizer to reproduce it:
make distclean make debug=1 ./bin/move /dev/urandom
[optional] Implement the ability to print the contents of the file's buffer to std::cout, and test it!
Exercise 5: raii.cpp (network port scanning with RAII)
Execute the following:
make distclean make ./bin/raii
Can you generate an assertion failure after a few executions? Where are the leaks in the program? For one of them, you can get more information with valgrind:
valgrind ./bin/raii
Correct the leaks, and verify by a few normal/valgrind executions!
Can you refactor port_scan() into a new port_scan2(), that applies RAII to its resources? You should not change anything in namespace net!
Exercise 6: thread.cpp (apply multi-threading to a simple task)
Execute the following:
make distclean make ./bin/thread
Note the duration output for the sorting of both containers.
Can you refactor task() into a new parallel_task(), that spawns two threads, each sorting one of the two containers? Execute the program a few times, and compare the execution times of task() and parallel_task().
Tip: keep copies of vec & deq in main and invoke parallel_task() on these (unsorted) copies, in order to compare the execution times of both sorting tasks!