Over time, you will learn which bugs you tend to introduce most often and will be able to catch those types of bugs while you are coding. That takes years of experience, but in your example, once you've been burned by a few missed null checks you'll learn to guard against nulls as you code.
TDD will eliminate a specific category of bugs caused by the output of a specific scenario not matching the expected result. However, this class of bug is just one of many, and depending on your type of application you're writing TDD might not give you the most value. When it's all said and done, a bug can have many root causes, and not having test-driven a unit of code is only one such cause.
Most often I find that bugs are introduced primarily due to:
If you lack knowledge, experience, interest, attention to detail, or time; no methodology or tool is going to eliminate bugs.
The reason the industry fixates on automated testing (in all of its various forms) as much as it does, is that the degree of automated tests can be measured and tracked over time. Anything that can't be measured is ignored as not being a source of bugs. As long as the prevailing software development management philosophy is grounded in the industrial era, this thinking will persist, and the more common and impactful root causes will continue to be ignored.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.