I've been out of C++ programming for several years, but I do remember a couple basic rules I followed that saved me from a lot of memory problems and invalid state problems. This may not be the kind of thing you're looking for, but here it goes...
1) Never allocate memory to a raw pointer. Never.
That is, if you allocate memory to something, it better be allocated to a smart pointer like auto_ptr or a reference counting pointer (boost.org at the time had a family of these). The only exception to this rule is in the implementation of the smart pointers themselves. You should be able to find a good number of articles on this.
2) Always follow the "strong exception safety guarantee".
Classes that provide this guarantee promise that they will not change their state if they throw an exception. Again, there are many articles. Here's an example of an assignment operator providing the guarantee (please forgive me if my C++ is not quite right - I'm rusty):
Whole::operator=(const Whole& that) {
auto_ptr tempPart1 = new Part(that.part1);
auto_ptr tempPart2 = new Part(that.part2);
this.part1 = tempPart1;
this.part2 = tempPart2;
}
The example is a class Whole with two dynamically allocated Parts. The assignment operator instead of having two lines of code - i.e. cloning the two parts and assigning them directly to the member variables - has four. It first clones the parts to temporary variables and then assigns them to the member variables. Why? Without the temporary variables, if the second "new" operation throws an exception (such as bad_alloc), the state of the class would be different and inconsistent from before the call. It would have one original part, and one part from the cloned class.
There are lots of other simple rules like this that can make code more solid, easier to read, and easier to maintain. If I remember right, the C++ FAQ from the C++ newsgroup contains a lot of them.