Most common source of bugs
There is one single source of most bugs. It’s obvious, yet almost nobody talks about it. That source is statistics.
You can call it a stretch, but it’s true. No matter how you classify a bug, whether it’s a race, a leak, whether a programming error, a typo or a misunderstanding, statistics influences whether that bug occurs or not in the first place.
Using mallocs/frees all over the code or using lots of gotos is not a source of bugs per se. Most occurrences of constructs widely perceived as bug prone will not produce an incorrect program. Until these constructs meet statistics.
If we put it this way, it sounds hopeless, because statistics quantifies everything around us, every programming technique. But we can use this fact to choose which programming techniques we use or even as far as which programming language we use, to reduce the number of bugs.
Using the above example, if we write a program explicitly calling malloc() and free() to allocate and release memory as needed, we will occasionally forget to call free() and introduce a memory leak in the code. In C++ the simplest solution to that is to never use free() or the delete operator, but to rely on destructors to do their job instead (e.g. the use of std::vector or std::make_shared() in C++11, etc.). This way we will never forget to free memory, the compiler will do this for us.