RAII in C++

RAII is one of the patterns in C++ to manage resources.

Sometimes at some part of the program, we need to allocate some memory and later free it.

template <typename T, std::size_t N>
T* allocateMemory()
{
return new T[N];
}
template <typename T>
void freeMemory(T *p)
{
delete[] p;
}
int main()
{
int *p = allocateMemory<int, 10>();
// use p
freeMemory(p);

return 0;
}
  1. freeMemory() is not called at all. There will be memory leak.
  2. freeMemory() is called twice from two different control paths or threads. It will cause double deletion and might crash.
  • Resource acquisition(memory allocation, file opening, acquiring mutex , database connection) is done when lifetime of the object begins. In C++11, lifetime of object begins after construction.
  • Resource is available throughout the object lifetime.
  • Resource is released when lifetime of the object object ends.
  • Destructor releases the resource and never throws an exception.
  • has lifetime that is bounded by the lifetime of an automatic or temporary object
  1. close the file in the destructor
  2. It has a method which takes a string to write into the file.
class FileHandlerRAII
{
public:
explicit FileHandlerRAII(const char* fileName)
: m_fp(std::fopen(fileName, "w+"))
{
std::cout << "file resource: " << fileName
<< " acquired" << std::endl;
}

bool write(const char *str)
{
if (std::fputs(str, m_fp) == EOF) {
return false;
}
return true;
}

~FileHandlerRAII()
{
std::fclose(m_fp);
std::cout << " file resource released" << std::endl;
}

private:
FILE *m_fp;
};
class BadFile: virtual public std::exception
{
public:
explicit BadFile(const std::string &msg): m_msg(msg) {}
virtual ~BadFile() throw () {}
virtual const char* what() const throw()
{
return m_msg.c_str();
}

private:
std::string m_msg;
};
class FileHandlerRAII
{
public:
explicit FileHandlerRAII(const char* fileName)
: m_fp(std::fopen(fileName, "w+"))
{
if (m_fp == NULL) {
throw BadFile(std::string(fileName) +
" failed to be opened.");
}
std::cout << "file resource: " << fileName
<< " acquired" << std::endl;
}

//....
~FileHandlerRAII()
{
if (m_fp != NULL) {
std::fclose(m_fp);
std::cout << "file resource released" << std::endl;
}
}

private:
FILE *m_fp;
};
FileHandlerRAII(const FileHandlerRAII &) = delete;
FileHandlerRAII(FileHandlerRAII &&) = delete;

FileHandlerRAII& operator=(const FileHandlerRAII &) = delete;
FileHandlerRAII& operator=(FileHandlerRAII &&) = delete;
int main()
{
FileHandlerRAII raii("test.log");
if (raii.write("Hello RAII")) {
std::cout << "file accessed successfully" << std::endl;
}
return 0;
}
file resource: test.log acquired
file accessed successfully
file resource released
int main()
{
try {
FileHandlerRAII raii("test.log");

for (auto i=0; i < 3; i++) {
if (raii.write("Hello RAII")) {
std::cout << "file accessed successfully"
<< std::endl;
}

if (i == 1) {
throw std::runtime_error("Bye bye cruel world !");
}
}
} catch (...) {
std::cout << "something went wrong" << std::endl;
}

return 0;
}
file accessed successfully
file accessed successfully
file resource released
something went wrong

C++11/14, Qt, Juce

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store