Удалить указатель на указатель (в виде массива массивов)
У меня это в моем коде:
double** desc = new double* [size_out];
for (int i = 0; i < size_out; i++)
desc[i] = new double [size_in];
Как удалить этот desc
?
Должен ли я делать:
delete [] desc;
или
for (int i=0; i<size_out; i++)
delete [] desc[i];
delete [] desc;
или
for (int i=0; i<size_out; i++)
delete [] desc[i];
delete desc;
?
Ответы
Ответ 1
Простые правила:
- для каждого распределения, должно быть освобождение (ex1 поэтому неверно)
- то, что было выделено с помощью
new
, должно быть освобождено с помощью delete
, использование new[]
должно быть освобождено с помощью delete[]
, а использование malloc
должно быть освобождено с использованием free
(поэтому ex3 поэтому ошибочно)
Заключение, ex2 в порядке.
Ответ 2
Ваше удаление должно отражать ваше распределение.
Поскольку вы использовали new []
для распределения внешнего массива и new []
(в цикле) для выделения внутренних массивов, выполните аналогичные действия для удаления. То есть: ваше второе решение правильно; delete []
внутренние массивы в цикле и, наконец, внешний массив через delete []
.
Тем не менее, лучшее решение ) в С++ должно было бы использовать вложенный std::vector
:
// Declaration and initialization:
vector<vector<double> > desc(size_out, vector<double>(size_in));
// No deletion!
Ответ 3
Ваш код не должен компилироваться. Тип нового выражения массива - это указатель на тип создаваемого элемента массива (значение является указателем на первый элемент выделенного массива).
Таким образом, тип new double**[size_out]
равен double ***
.
Всякий раз, когда вы используете форму массива new, вы должны использовать форму удаления массива, даже если вы выделяете только массив размером один.
double*** desc = new double**[size_out];
for (int i=0; i<size_out; i++)
desc[i] = new double*[size_in];
for (int i=0; i<size_out; i++)
delete[] desc[i];
delete[] desc;
Обратите внимание, что вы все еще не выделили double
, просто указатели.
Вы действительно этого хотели?
double** desc = new double*[size_out];
for (int i=0; i<size_out; i++)
desc[i] = new double[size_in];
for (int i=0; i<size_out; i++)
delete[] desc[i];
delete[] desc;
Ответ 4
Решение 2 является правильным: каждая ячейка указывает на динамически выделенный массив, который следует удалить с помощью delete[]
. В заключение,
сам массив desc
должен быть удален с помощью delete[]
.
Бонусное решение 4: не используйте массивы и не переключайтесь на std::vector<std::vector<double> >
.
Ответ 5
Я бы сделал
for (int i=0; i<size_out; i++)
delete [] desc[i];
delete [] desc;
для каждого массива, выделенного с помощью new []
, у вас есть соответствующий delete []
.
Изменить: и, как говорит Рупдольф, прекратите использование C-массивов и начните использовать std::vector
. У вас будет (я имею в виду стократное!) Меньше ошибок.