RAII

Resource Acquisition Is Initialization

Thameera Senanayaka

Allion Technologies

Classic memory leak scenario

void render()
{
  LEParam* oLeParam = new LEParam();

  // ...

  delete oLeParam;
}

What if an exception is thrown in the middle of the code?

Solutions

  • Create LEParam in the stack
  • Use std::shared_ptr

Database connections

void getData()
{
  Database db = new Database(URI);

  db.connect();

  // ...

  db.close();
}

Mutexes

std::mutex mu;

void f()
{
  mu.lock();

  // ...

  mu.unlock();
}

RAII

Aishwarya Raii

RAII

  • Encapsulate a resource into a class
  • Use the resource via a local instance of the class
  • Resource automatically gets freed when the instance gets out of scope
  • Exception-safe

Mutexes with RAII

class Lock
{
public:
  Lock(std::mutex &mu) : mu_(mu) { mu_.lock(); }

  ~Lock() { mu_.unlock(); }

private:
  std::mutex &mu_;
};

What if Lock was copied?

Lock a(&mu);
Lock b(a);

Copy behavior in RAII

  • Make object uncopyable

or

  • Use reference counting

Making it uncopyable

class Lock
{
public:
  Lock(std::mutex &mu) : mu_(mu) { mu_.lock(); }

  ~Lock() { mu_.unlock(); }

private:
  std::mutex &mu_;

  Lock(Lock const &);  // copy ctor
  Lock& operator=(Lock const &);  // copy assignment ctor
};

Case study

In Preprocessor,

startup::core::memory::ScopedPtr

Using std::shared_ptr for RAII

Use a custom deleter

std::shared_ptr<T>(obj, deleter);

Using std::shared_ptr for RAII

void custom_deleter(Image* img)
{
  delete img;
}

shared_ptr<Image> img(new Image(), custom_deleter);

Using std::shared_ptr for RAII

std::shared_ptr<Image> img(new Image(), [](Image *img) {
  delete img;
});

with lambdas

Thank you!

RAII

By Thameera