And there you have one of the most badly handled aspects in C++/C and similar languages: object ownership. You have to handle it yourself. This gives result to either double deallocation, or failure to deallocate. Of course if you keep everything localized, and/or use smart pointer classes, this alleviates the problem. But even so this gives rise to weirdo situations and some weirdo programming constructs that are hard to fathom for some people of average programming capabilities.
Now to say that garbage collection rules out all memory leaking, is also not true. There will always be unmanaged resources (meaning not managed by the environment), or external resources, that you need to deallocate or release yourself. For instance if you need aligned memory blocks for IO or DMA, you still need to defer to OS libraries that are often C++/C based, and those give you pointers to memory instead of references. Another thing is forgetting to dereference objects. Other times you have to defer to environment constructs that in themselves might lead to memory loss due to badly written software.
That coupled with the fact that programmers tend to think they are safe from memory loss in their garbarge collected environment, may result in memory loss that is never found because people think it doesn't happen. And then you have the programmers that didn't have any proper education... they will look at you if you explain all that as if you are a stupid arcane C++ era programmer, that needs to boast with his knowledge.
Java, .NET, they brought some good things to programming languages, but they also brought some bad programmers and bad programming to the business. Not all is roses and sunshine.