С++ удаляет массив, даже если возникает ошибка

Я новичок в С++, исходя из С#. Вот код:

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

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

   delete[] array;
   return;
}

Я знаю, что в С++ нет эквивалента С# using.

Есть ли простой и элегантный способ гарантировать, что память будет выпущена, что когда-либо произойдет?

Ответ 1

В С++ код выглядит следующим образом:

#include <vector>

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

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

    return;
}

Если вы действительно не хотите инициализировать элементы массива и не нуждаетесь в изменении размера массива и не нуждаетесь в итераторах, вы также можете использовать:

#include <memory>

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

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

    return;
}

В обоих случаях вы получаете доступ к элементам массива с помощью array[0], array[1] и т.д.

Наконец, если вам не нужно передавать права собственности на данные из функции, знайте размер массива во время компиляции, а размер не слишком велик, вы также можете рассмотреть вопрос о наличии объекта прямого массива

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;
}

Ответ 2

Автоматические переменные автоматически уничтожаются в конце области, будь то из-за возврата или броска:

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

извините за вводящий в заблуждение пример, размер массива неизвестен во время компиляции

В этом случае вам нужен динамический массив. Популярным решением для обработки очистки ресурсов, таких как динамическая память, является перенос указателя (или дескриптора в зависимости от типа ресурса) в классе, который приобретает ресурс при инициализации и выпускает при уничтожении. Затем вы можете создать автоматическую переменную этого типа обертки. Этот шаблон называется "Сбор ресурсов инициализацией" или RAII для краткости.

Вам не нужно писать собственную оболочку RAII для динамического массива. В стандартной библиотеке вы рассмотрели: std::vector