Show Lecture.RAII as a slide show.
CS253 RAII
Worst Acronym Ever
RAII means:
Resource
Acquisition
Is
Initialization
Very Slightly Better
CADRE means:
Constructor
Acquires
Destructor
Releases
Definition
- RAII means: acquire the resource when you create the variable,
and let the dtor release the resource.
- If you catch yourself thinking “must remember to clean this up”,
then you should be using RAII.
- The object remembers to do the cleanup.
Non-RAII code
Here’s some non-RAII code:
// Acquire resources
FILE *host = fopen("/etc/hostname", "r");
float *scores = new float[253];
char *name = new char[50];
// Use resources
cout << "hi there\n";
// Clean up after ourselves
delete[] name;
delete[] scores;
fclose(host);
hi there
RAII code
The equivalent RAII code:
// Acquire resources
ifstream host("/etc/hostname");
unique_ptr<float> scores(new float[253]);
string name(50, 'X');
// Use resources
cout << "hi there\n";
// Clean up after ourselves
hi there
Why?
It’s not too difficult to remember to free our
resources, but what if something gets in the way?
float *scores = new float[253];
if (getpid() != 0) {
cerr << "Must be super-user!\n";
return 1; // Forgot to delete scores!
}
cout << "hello\n";
delete[] scores;
Must be super-user!
Sure, we could add delete
[] scores
to the if
clause,
but what if there are several early returns, and many variables?
It’s not very DRY. Also, what about exceptions?
Why.
// Should just use a vector<float>
unique_ptr<float> scores(new float[253]);
if (getpid() != 0) {
cerr << "Must be super-user!\n";
return 1;
}
cout << "hello\n";
Must be super-user!
This code isn’t bothered by early returns or exceptions. They will both
cause the unique_ptr
to be destroyed, and its dtor will free the
memory.
Simplicity of Description
Consider this non-RAII code:
double *p;
// … region 1 …
p = new double[100];
// … region 2 …
delete p;
// … region 3 …
Descibe p
in the various regions:
- uninitialized, indeterminate
- pointing to 100 doubles
- indeterminate; probably a stale pointer to the ex-doubles
Simplicity of Description
Consider this RAII code:
unique_ptr<double> p(new double[100]);
// … region 1 …
Descibe p
in the various regions:
- pointing to 100 doubles
Gosh, that seems easier to understand.
Other Uses
Use RAII when you think “Don’t forget to …”, which might apply to:
- dynamic memory
- files
- mutex
- network sockets
- opening a database
Real-Life RAII
- I treat my teaching assistants as a form of real-life RAII.
- When I need a quiz graded, I don’t give them step-by-step
instructions:
- First, take the quizzes to your office.
- Second, grade the quizzes.
- Third, enter the grades.
- Fourth, return the quizzes so I can given them back to the students.
- No! I say “Here are the quizzes. Do it!” and it gets done, no matter
how often the TA gets interrupted by their life.
- A TA knows how to grade & return quizzes.
- A
vector
knows how to allocate & free memory.
Real-Life RAII