Some memory issues with code you might be familiar with... From your own repo.
https://github.com/AndrewBelt/game_of_life/blob/master/src/g...
Not checking for return values is not a great idea. Your code blows up phenomenally with certain "width" and "height" values. It does check against negative grid sizes, but that's not enough (https://github.com/AndrewBelt/game_of_life/blob/master/src/g...)!
With suitable width & height it'd also gladly free a "grid" it never allocated. Of course it crashes long before that happens.
Ok, so it was cloned from someone else's repo, and you never got around cleaning it up.
Let's see...
https://github.com/AndrewBelt/bored/tree/master/src
Ok, still not checking return (SDL, etc.) values. Debug build asserts are better than nothing -- didn't bother to check how your build is configured.
https://github.com/AndrewBelt/bored/blob/master/src/map.c#L3...
and then access it:
https://github.com/AndrewBelt/bored/blob/master/src/map.c#L4...
Here if realloc() fails, you'll have a memory leak and, again, accessing NULL later:
https://github.com/AndrewBelt/bored/blob/master/src/priq.c#L...
There is also integer overflow: alloc is int, so if it becomes greater than 2^31-1, it may wrap around [I think signed int behaviour in C is undefined in this case], and you'll allocate fewer bytes than needed, leading to buffer overflow.
And another to be honest, very few programs on desktops/mobile are actually checking return values of malloc/calloc, because of amount of data that program operates is usually much smaller than amount of RAM available. It's sure a case for embedded, but you simply usually don't use malloc for embedded.
Well, if that is true, you are either very lucky or very brilliant. I have written moderate amounts of C, and I have run into those problems repeatedly.
Maybe that just means I am an idiot, but it appears that smarter people than me make such mistakes as well (although less frequently, I hope). C - at least when compared to most other popular languages - makes it very easy to make such mistakes.
> Why does so much work go into fixing these problems?
Because these problems have cost lots and lots of money thanks to crashing or misbehaving software (including many a security problem). Not to mention the sanity of the programmers who had to debug these...
(Also, I am told that in embedded/realtime software memory management is a lot simpler, as malloc/free are typically not used; you didn't say what kind of C code you have written, but if you are an embedded developer, that would at least partially explain your experience.)