15

About these assignments As someone who’s been teaching C++ for 15 holy shit, almost 20 years now, I have to say that these assignments are pretty terrible… especially the “vector” one. (To be clear, I mean the assignments are terrible… not the attempts. The attempts aren’t bad at all.) I’ve always found the logic of “let’s teach by reimplementing what’s in ...


13

Design review Trying to roll your own shared_ptr is actually a really good practice project. This is not true for many other standard library components, but it is true for shared_ptr. You could try to duplicate the behaviour of std::shared_ptr exactly… but you don’t need to, because there are actually many, many different smart pointer designs. The ones in ...


9

template <class K, class D> bool Block<K,D>::insert(const K &key, const D &data) { bool result = false; const std::lock_guard<std::mutex> lock(m_slotMutex); if (m_slots.find(key) == m_slots.end()) { m_slots[key] = data; result = true; } else { //Key already present , cant insert ...


8

It will leak memory. Aside from not having move constructor or assignment, a big problem is that the assignment operator does not decrease the count for the assigned to object ("this", the value on the left of the equals sign). The result is that the memory allocated when sp5 is constructed is not freed when it is replaced using sp5 = sp4;. One way ...


7

Building-blocks only ever interact directly with the user in two circumstances: A violation of program invariants is detected and the program must be shut down immediately to avoid further damage. Normal output is wrong for that, logging and error-stream resp. error-prompt are appropriate. The purpose of the code is interacting with the user. Everything ...


6

Design Your design pays all the costs std::shared_ptr does and then some, but drops many of the capabilities. The smart-pointer itself is not smaller (assuming int is at least as big as a pointer, or the latter has alignment equal to size). Create and destroy enough of your smart pointers, and your id overflows. Hilarity ensues. The bookkeeping is likely ...


6

Fix buffer overrun in copy_small As you've currently written it, and as Toby previously pointed out, copy_small always writes 8 bytes to dest, even when size < 8. This is a major memory safety bug as it writes past the end of the dest buffer. void copy_small(void *restrict dst, const void *restrict src, size_t size) { const uint64_t *restrict src64; ...


4

const uint64_t *restrict src64; Portability problem - uint64_t is only defined if the platform has a type of exactly 64 bits. Consider using uint_fast64_t (or perhaps uintmax_t) instead. pages = words / 8; offset = words - pages * 8; Another portability problem - assumes CHAR_BIT is 64/8 = 8. Use sizeof *src64 instead. The terminology is strange and ...


3

Let's start up top: void print_array(int[], size_t); void merge_sort(int[], size_t, size_t); You declare two functions here, but what are their semantics? For a start, be aware that this is just a different spelling for void print_array(int*, size_t); void merge_sort(int*, size_t, size_t); So, both functions receive a pointer as first argument. I for one ...


3

The single most important advantage of merge sort is its stability. The elements compared equal retain their original order. Your code loses stability. If l[i] compares equal to r[j], the latter is merged first. Your code assumes closed ranges (that is, end is a valid index). That leads to some unpleasant fiddling with indices. Semi-open ranges (that is, ...


3

Is that just for type hints? Correct, everything in the typing module is used for type hints. These are useful when using something like mypy, but the python interpreter will just ignore all of these. Would it be faster to use numpy arrays instead of python lists of lists? Theoretically, yes but it depends on the size of the data. numpy is really meant ...


3

Your ValueStore template class always has a value. If you don't call the one-argument constructor, it holds a default-constructed value. That might work OK if the type T has a default. Just chalk it up to your teacher's language being imprecise, as we see with other phrases like "Use the class to store three values of different types." (...


2

Updated results, tests and code As per suggestions in this thread I have updated my code following several suggestions from the answers. If I have incporporated your code in the result, I want to note that I need to follow certain strict formatting rules so sorry if I've changed the formatting in places. Test scenario I have created the following test ...


2

My only suggestion would be to user itertools.count() instead of implementing your own counter. Something like: from itertools import count _global_counter = count() def auto(): return next(_global_counter)


2

Consider adding PEP484 type hints. I needed to go through this to make some sense of the values you're passing around. not being OS specific - indeed. Your call to cls has dubious security value, and if you deem it to have such value, it's better to call into a cross-platform library that will accomplish the same thing. Currently you're pegged to Windows ...


2

Once thing that I feel particularly strongly about: if (v3.hasValue) { cout << "The value stored is: " << v2.getValue() << endl; } else { cout << "v3 has no value." << endl; } The duplication of this code should be removed if at all possible. It's a maintenance nightmare, it makes life harder for the ...


1

Spacing! Separate function definitions with blank lines. I'd use a, b, c for type variables and x, y, z for variables. A . looks cleaner than a $. putStr . unlines . map show . fib $ read s :: Int I would add another pair of parentheses to make the order of application absolutely obvious. (l:ls) !: a = l : (ls !: a) For similar reasons, I prefer the ...


1

First a few small things: If you expect this to be used in other programs, it should be documented: comments to explain implementation choices and details and docstrings to explain how to use the classes and functions in the module. A small suggestion: When modeling something, it is often helpful if the interface uses the same numbering or nomenclature used ...


1

last_thing You define last_thing and use it to initialise your array, which is fine, however you also use it within your actual bubble_sort function. This seems wrong, it would be better to use the length of the supplied array in order to determine when to stop. This will make your code more portable and able to handle different sized arrays. When to check ...


Only top voted, non community-wiki answers of a minimum length are eligible