Pointers are very efficient in use but they make it very easy to foul something up. Can we be safer with our pointers?
Smart Pointers
In any new software use smart pointers instead of raw pointers unless you are trying to eke out every last cycle of performance. You can even even call functions that require raw pointers as you can get at the underlying raw pointer using the get method.
#include <memory>
std::unique_ptr<std::string>> smart_pointer = make_unique<std::string>>();
They are a lot more verbose than raw pointers, but in general the advantages outweigh the disadvantages.
Uninitialized Pointers
Always initialize your raw pointers. This is not optional. If you don’t know what they are going to be set to, then initialize them to nullptr. An uninitialized pointer is pointing… somewhere. It could be to memory that you have no access to or even memory in your virtual memory. This could lead to application crashes or some of your data being subtly being altered, leading to a hard to track down bug.
int *raw_ptr {};
It’s really that easy.
Dangling Pointers
Always reset a pointer after freeing heap memory and never return a pointer to a local variable. Get into the habit of doing these and that’s a whole class of bug eliminated.
int *heap_int = new int {};
// Do loads of stuff
delete heap_int;
heap_int = nullptr;
Always do this ^
Object *function() {
Object object;
return &object;
}
Object *my_object = function();
Never do this ^. You now have pointer to an object that has been deleted from the stack.
Sentinel Values
If you’re not trying get every last drop of performance, always use sentinel checks when using raw pointers. This will prevent you from using a pointer to nullptr.
int *ptr {};
// Do lots of stuff
if (ptr) {
std::cout << *ptr;
}
If you are in a situation where you have multiple pointers to the same thing, keep it clear in your head which is the main pointer and only delete any heap memory using that one. Also add it to any sentinel checks.
int number = new int {};
int *main {&number};
int *ptr {main};
// Do lots of stuff
if (main && ptr) {
std::cout << *ptr;
}
// Do lots of stuff
delete main;
main = nullptr;
ptr = nullptr;
Memory Leaks
Linux has a tool called valgrind that will find memory leaks and I’m sure that both Windows and Mac have similar tools. Use them. Track down your memory leaks and fix them. Sure it’s a bit of an effort, but it’s worth it.