The primary way to avoid this is to simply avoid using new or delete under any but the most tightly controlled circumstances.
Using new inside of main is particularly suspect -- the reason to use new in C++ is when you need to create an object that needs to outlive the scope in which it's being created (e.g., when you reach the end of that function, it must not be destroyed). In the case of main, the only reason to do what would be if you were allocating something in main that would not be deleted in main, but used by some the destructor of some global object as it ran after you returned from main (which is rarely done and even more rarely a good idea).
Most uses of new should be in the ctor of an object, and most uses of delete should be in the dtor of an object. If you have something like a collection, it can also make sense to use new and/or delete in some other member function(s) that handle(s) things like re-sizing the collection.
Other than that, there are entity objects that generally aren't ever assigned or copied. For example, consider a call routing system, where you create a "call" object when somebody dials their phone, and you destroy the object when they hang up. In nearly every such case, you have a global collection (or more than one) that holds pointers to these objects, so as soon as you create the object, its address goes into the (correct) global collection. Interesting point: nearly all code that I've seen where this pattern made sense did not have any external code that destroyed the object -- rather, the object itself was responsible for removing itself from the global connection, and using the (much argued-about) delete this; to destroy itself when the real-world connection (or whatever) it was attached to ended.