Pointer safety in C++

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.

 

 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.