Each item in Wikipedia's [list of types of memory errors](https://en.wikipedia.org/wiki/Memory_safety#Types_of_memory_errors) and what Crowbar does to prevent them. # Access errors ## Buffer overflow Crowbar addresses buffer overflow with bounds checking. In C, the type `char *` can point to a single character, a null-terminated string of unknown length, a buffer of fixed size, or nothing at all. In Crowbar, the type `char *` can only point to either a single character or nothing at all. If a buffer is declared as `char[50] name;` then it has type `char[50]`, and can be implicitly converted to `(char[50])*`, a pointer-to-50-chars. If memory is dynamically allocated, it works as follows: ```crowbar void process(size_t bufferSize, char[bufferSize] buffer) { // do some work with buffer, given that we know its size } int main(int argc, (char[1024?])[argc] argv) { size_t bufferSize = getBufferSize(); (char[bufferSize])* buffer = malloc(bufferSize); process(bufferSize, buffer); free(buffer); } ``` Note that `malloc` as part of the Crowbar standard library has signature `(void[size])* malloc(size_t size);` and so no cast is needed above. In C, `buffer` in `main` would have type pointer-to-VLA-of-char, but `buffer` in `process` would have type VLA-of-char, and this conversion would emit a compiler warning. However, in Crowbar, a `(T[N])*` is always implicitly convertible to `T[N]`, so no warning exists. (This is translated into C by dereferencing `buffer` in `main`.) Note as well that the type of `argv` is complicated. This is because the elements of `argv` have unconstrained size. TODO figure out if that's the right way to handle that ## Buffer over-read bounds checking again ## Race condition uhhhhh 🤷‍♀️ ## Page fault bounds checking, dubious-pointer checking ## Use after free `free(x);` not followed by `x = NULL;` is a compiler error. `owned` and `borrowed` keywords # Uninitialized variables forbid them in syntax ## Null pointer dereference dubious-pointer checking ## Wild pointers dubious-pointer checking # Memory leak ## Stack exhaustion uhhhhhh 🤷‍♀️ ## Heap exhaustion that counts as error handling, just the `malloc`-shaped kind ## Double free this is just use-after-free but the use is calling free on it ## Invalid free don't do that ## Mismatched free how does that even happen ## Unwanted aliasing uhhh don't do that?