2

I've been attempting to learn C++, but it is famously plagued by bad tutorials. I learned about a clever little trick called RAII (Resource Acquisition is Initialization), where one wraps a heap variable in an object placed on the stack. One would free the resources in the destructor of this object, so one would not have to worry about calling delete on the heap based object. However, I also know that you are supposed to create as few objects as possible, as to save RAM. Which brings me to my question, how much should I use RAII? Especially in a project that creates a lot of heap variables.

1 Answers1

7

How often should RAII be used?

As often as it makes sense to use (that is, whenever you have an operation that will need to be inverted/undone/closed/finalized/committed/etc. you should probably use RAII).

However, I also know that you are supposed to create as few objects as possible, as to save RAM.

No; This is a form of premature optimization which is bad enough, but it also relies on a fallacy:

The number of variables in the code should not be a limiting factor in using RAII, because if you need a variable allocated, the allocation will be the same, whether it is in a wrapper or raw. An extra RAII wrapper will not add anything significant to the memory footprint of the application.

In other words, the following pieces of code should have the same (or comparable) memory footprints:

resource* allocate_resource() { return new resource{}; }
void release_resouce( resource * r ) { delete resource; }

// client code
auto r = allocate_resource();
release_resouce(r);

and

struct resource_ptr {
    resource * r_;
    resource_ptr() : r_ { new resource }{}
    ~resource_ptr() { delete r_; }
};

// client code:
resource_ptr p;

Both the resource* in the first sample and the resource_ptr instance in the second will have the same size (4 bytes on 32bit systems) and the calls to new/delete are in separate functions (which again, should have the same footprint whether in a structure or at top-level).

Something to keep in mind:

RAII can also be translated to mean "Responsibility acquisition is initialization", in which case, it will mean something more abstract (and larger) than "pointer/resource release in destructors". It effectively applies to any operation that requires a counter-operation later:

  • files that are opened will need to be closed
  • database transactions will need to be committed or rolled back
  • mutexes that are locked will need to be unlocked
  • network connections that have been opened will need to be closed

None of these are heap variables, but RAII applies naturally to all of them.

utnapistim
  • 5,313