Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ delete array even if error occurs [duplicate]

I am new to C++, coming from C#. Here is the code :

void function(int n)
{
    double* array = new double[n];

   //some work that can return or throw an exception
   //...

   delete[] array;
   return;
}

I know there is no C# using equivalent in C++.

Is there a simple and elegant way to ensure that memory will be released what ever happens ?

like image 265
Sylvain B. Avatar asked Feb 01 '17 14:02

Sylvain B.


2 Answers

In C++, the code would look as follows:

#include <vector>

void function()
{
    std::vector<double> array(100);

    //some work that can return when or throw an exception
    //...

    return;
}

If you really don't want to initialize the array elements and don't need to resize the array and don't need iterators, you can also use:

#include <memory>

void function()
{
    std::unique_ptr<double[]> array(new double[100]);

    //some work that can return when or throw an exception
    //...

    return;
}

In both cases you access the array elements with array[0], array[1], etc.

Finally, if you don't need to transfer ownership of the data out of the function, know the size of the array at compile time, and the size isn't too large, you may also consider having a direct array object:

void function()
{
    double array[100];  // uninitialized, add " = {}" to zero-initialize

    // or:

    std::array<double, 100> array;  // ditto

    //some work that can return when or throw an exception
    //...

    return;
}
like image 93
Kerrek SB Avatar answered Oct 01 '22 00:10

Kerrek SB


Automatic variables are destroyed automatically at the end of scope, whether due to return or a throw:

{
    double array[100];
    throw 1; // no memory leaked
}

sorry for the misleading example, the size of the array is not known at compile time

In that case you do need a dynamic array. A popular solution to handling cleanup of resources such as dynamic memory is to wrap the pointer (or handle or descriptor depending on the type of resource) in a class, that acquires the resource on initialization, and releases on destruction. Then you can create an automatic variable of this wrapper type. This pattern is called "Resource acquisition is initialization" or RAII for short.

You don't need to write your own RAII wrapper for a dynamic array however. The standard library has you covered: std::vector

like image 25
eerorika Avatar answered Sep 30 '22 22:09

eerorika