Variables on the stack

I think one very underused feature in C++ today is simply storing objects on the stack. Many developers who have started writing C# or Java are used to always using new to declare a variable and do the same thing when they are writing C++. And when they later learn that you should never write a naked new, they instead start using unique_ptr or shared_ptr to manage the lifetime of their objects. What they are forgetting is that many times is it sufficient to simply store the instance that you are creating on the stack as a solid object, either as a member of a class or in the local function scope.

The standard library does this all the time, you write

never ever

If you are certain what type of object you need and when you need it, then simply put it on the local stack!

For often called methods you will get a performance increase by doing this since the allocation of an object on the free store takes some time (new has to locate a free portion of memory to allocate).

The exceptions where you don’t want to allocate the object on the local stack include cases where you may want polymorphic behavior, or the class contains large amounts of data making the object too large for the stack.

Facebookgoogle_pluslinkedinmail

Using RAII to raise the current thread priority temporarily (Windows specific)

In a recent project I had the need to raise the priority of the currently executing thread for a short period of time while an important I/O operation was being performed (the device which the data was read from didn’t have a buffer to store the data hence the reading thread had to be ready at all times to receive the data). I ended up creating a helper class which uses RAII to manage the priority of the current thread. When the object is created on the local scope the priority of the thread is raised and when the object goes out of scope then the destructor will make sure that the priority of the current thread will go back to its original value.

The class deletes the overload of the operator ‘new’ which makes sure that it is impossible to create the object on the free store.

The code to get the current thread and to change the thread priority is Windows specific but I guess this can quite easily be modified to fit other OS:s as well.

 

 

 

Facebookgoogle_pluslinkedinmail

Free store vs Heap

There is much confusion regarding the usage of the words stack, heap and free store. Most developers are using the stack and heap wrongly for C++.

Stack

The stack (actually the call stack) is the memory where all your local variables in a function will be located. The stack is a memory structure where all the function calls, from the start of the current thread, up to the currently executed function are stored together with the memory that they use. The variables which reside on the stack are stored there until the function where they reside returns. Once the method returns then all local (stack) variables will be cleaned up.

Heap

The heap is a legacy from C which should not be used in C++. Objects on the heap are allocated using malloc or calloc and released again using free. You should never use malloc or calloc to allocate an object in C++. This since these calls does not call the constructor of the object, leaving you with allocated memory for an invalid object.

Free Store

The free store is in C++ what the heap was in C. Objects on the free store are allocated using new or new[] and released again using delete or delete[]. Objects allocated using new or new[] are allocated and their constructor is being called once the memory is allocated. Objects destroyed using delete or delete[] have their destructor called before the memory is released again.

Facebookgoogle_pluslinkedinmail

Constructor – creating the object

The constructor is a special function used to setup an object to a valid state.

  • The constructor must have the same name as the class.
  • The constructor does not have a return type.
  • There can be many constructors for the same class, the difference between them is the number and type of the parameters.

A constructor without any parameters is called the default constructor. If you don’t write a default constructor then one will be created for you automatically and setup the object with default values (which may not be what you want).

The constructor of the object is together with the destructor an important part of the RAII paradigm.

Multiple constructors

A class can have many constructors, and one common problem is that these will usually perform the same initialization of the member variables thereby creating redundant code. With the interest of keeping your code DRY, you should consider to extract the common elements into separate functions. The, in many cases, most natural solution to this would be to make the constructors call each other – but there is a pitfall here. Calling one constructor from another will only work in C++11, so if you have a compiler which supports C++11 you can do the following (called delegating constructors):

If you don’t have a C++11 compiler then the common solution is to extract a separate function which does the initialization:

 

Private Constructor

Normally is the constructor of a class a public member function. If a class has a private constructor, then it is not possible to create instances of the class anywhere else but in the class itself. This can be handy if you want all instances to be created in exactly the same way or in the same location using a static factory method.

 

 

Facebookgoogle_pluslinkedinmail

RAII – Resource Acquisition Is Initialization

Resource Acquisition is Initialization (or RAII for short, usually pronounced by simply spelling out the letters R-A-I-I) is a programming technique where we make sure that resources are cleaned up when they are no longer needed by tying a resource to an object. The resource is kept as long as the object is alive and automatically released when the object is destroyed.

The resource that is being managed can be a segment of memory, a file handle, a network socket, a database handle or anything else which there is just a limited number of in the system and which we need to make sure we close properly after we are done with it.

The way RAII works is that we tie the resource to a class. When an instance of the class is created then the constructor of the object’s class is called to create the resource (or passed the resource to be managed). When the object is later destroyed (by going out of scope) then the destructor will automatically be called and here we write the code to release the resource again.

The name is somewhat difficult and controversial, some have suggested instead calling it Scope-Bound Resource Management but this has so far not been too successful.

I think an example of what I mean is necessary here. In the example below is a segment of memory allocated (using new[]) in the constructor of the File class and the memory is released again (using delete[]) in the destructor. The neat thing here is that the destructor will automatically be called when the object goes out of scope, as is done when the function main() in the example exits.

Notice: this is only done automatically for you if the File object is allocated as a local object, this is one of the reasons why you should never use new or delete.

The benefits of RAII is that it creates:

  • exception safety: a stack object will be destroyed at the end of the enclosing scope,  also if an exception is thrown from the code after the object is created.
  •  good locality: the code for allocating the resource is in the same class as the code for releasing the resource again.
  • encapsulation: the managed resource is located inside the owning class and not accessible outside of it.

Because of its benefits is RAII used extensively throughout the standard library classes.

As an example, the following code is using old C functions to write data to a text file NOT using RAII.

In the example above we didn’t use RAII to hold on to the resource (which in this case is the file handle FILE* f). This makes the code not exception safe, if anyone would later add a function call after the file has been opened and this method throws an exception then the call to fclose will not be executed at all, leaving the file opened and locked.

A better example is to instead use the standard library to open and write to the file:

in this example does the instance of the standard library class std::ofstream which we create on the first line hold on to the file resource and when the object goes out of scope when the function ends then the file will be closed automatically for us. Notice how much shorter and cleaner this code becomes. We don’t have to worry about closing the file since this is done for us.

References

  1. Stroustrup: Why doesn’t C++ provide a “finally” construct?

 

Facebookgoogle_pluslinkedinmail

Destructor

The destructor in a class is a special member function which takes care of cleaning up the contents of the object when it goes out of scope.

  • There can only be one destructor function per class.
  • The name of the destructor is the name of the class itself preceded with a tilde (~). It takes no arguments and does not have a return type.
  • The destructor is automatically called when an object goes out of scope.

A destructor is needed if the class holds or uses any resources which must be released when the object is destroyed, such as file handles or pointers to allocated memory. In a simple class which does not hold any resources then a destructor is not necessary since C++ will automatically clean up the memory that the object used. You also don’t need to write a destructor if the class holds resources through smart pointers (like unique_ptr) or standard library containers like std::vector as these will automatically delete themselves when they go out of scope. Notice that if you need to write a constructor in a class and intend to later on inherit from the class that you are writing now then you must make the destructor virtual (see the post on virtual destructor).

Example of a class where a destructor is necessary:

Example of a class using string from the standard library which makes it possible to avoid writing a destructor:

The destructor is an important piece in the automatic cleaning up of resources necessary for RAII.

Facebookgoogle_pluslinkedinmail

Scope

The scope of a variable determines who can see and use the variable and for how long the variable will be available until it is destroyed.

Local scope

Function parameters and variables declared inside a function (local variables) have local scope. That is to say that they can only be seen inside the function that declares them. The local variables are destroyed when the function exits and can no longer be accessed after the function exits.

Local scope prevents naming collisions. It is possible to have two variables with the same name, as long as they are in different scopes!

Be aware that it is possible to have nested scopes where two variables can exist with the same name but in different scopes, one inside another.

What happens in the example above is that within the nested block is a new variable ‘x’ created and this variable has its scope set to the local block which is smaller than the function main. Inside the nested scope is the outer variable ‘x’ not accessible it is hidden from view (this is called name hiding), only the variable ‘x’ declared in the inner scope can be seen and modified.  Notice that it is generally bad practice to declare a new variable with the same name is a smaller scope. The code quickly gets much more confusing when you have to remember which variable with the name ‘x’ you are seeing.

In the same way is it possible to declare a local variable with the same name as a function parameter.

This is also a bad practice and should always be avoided since it makes the code so much more difficult to read.

 

Facebookgoogle_pluslinkedinmail

Stack Unwinding

Stack unwinding refers to the handling of exceptions in C++. When an exception occurs then the call stack is searched for the next matching catch statement and the execution of the program is continued at the beginning of the catch clause. No other code in between is ever evaluated.

This is to say that for the functions

Then the program will never output any of the output statements!

However, and this is important, if the function f3() above did instead look like this:

then the cout statement would not be called, but the destructor of Date would be called. All local objects will be destructed when an exception happens, in the reverse order they were constructed.

 

Facebookgoogle_pluslinkedinmail

Memory leaks in constructions

Say that you have found somewhere deep in the darkest basement the following line of code

then you have found a potential memory leak in your program.

Why?

Remember that, calling new Date() will:

  1. Allocate memory for Date
  2. Construct the new Date object in that memory. If the construction fails because of an exception, then the allocated memory is freed again.

The compiler is free to evaluate the expressions in any way it seems suitable (the reason for this is that it has the ability to optimize the code if given some slack, see order of evaluation).  It can for example do like this:

  1. Allocate memory for Date
  2. Construct Date
  3. Allocate memory for Time
  4. Construct Time
  5. Call fun

The problem here is that if either step 3 or step 4 fails because of an exception, the C++ standard does not require that the Date object must be destroyed and its memory deallocated. This is a memory leak!

Another possibility is that the compiler does this:

  1. Allocate memory for Date
  2. Allocate memory for Time
  3. Construct Date
  4. Construct Time
  5. Call fun

In this case, then there are actually two problems.

1) If step 3 fails because of an exception, then the memory allocated for Date is automatically deallocated (step 1 is undone), but the standard does not require that the memory allocated for the Time object be deallocated. The memory is for the Time object is leaked.

2) If step 4 fails because of an exception, then the Date object has been allocated and fully constructed, but the standard does not require that it be destroyed and its memory deallocated. The memory of the Date object is leaked.

 

 

 

 

Facebookgoogle_pluslinkedinmail