Правильно ли это освобождение? - PullRequest
4 голосов
/ 11 июня 2009

У меня есть двумерный динамический массив 3x3, выделенный как показано ниже:

int** matrix = new int* [3];
matrix[0] = new int [3*3];
for (int i = 1; i < 3; ++i)
    matrix[i] = matrix[i-1] + 3;

Как мне его освободить? Это правильно:

delete [] matrix;

delete [] matrix[0];

Или я тоже должен удалить matrix[1], [2]

Ответы [ 6 ]

8 голосов
/ 11 июня 2009

Как у вас есть, вы должны:

delete [] matrix[0];
delete [] matrix;

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

// allocate
int **matrix = new int*[3];
for(int i = 0; i &lt 3; ++i)
  matrix[i] = new int[3];

// deallocate
for(int i = 0; i &lt 3; ++i)
  delete [] matrix[i];

delete [] matrix;
6 голосов
/ 11 июня 2009

код:

delete [] matrix;
delete [] matrix[0];

явно неверно, так как вы используете матрицу после ее удаления.

delete [] matrix[0];
delete [] matrix;

правильно, но я не могу подтвердить, что код в целом делает что-то разумное.

Обратите внимание, что вы не должны удалять matrix [1] и matrix [2], так как они являются просто копиями матрицы [0]. Практическое правило заключается в том, что вы должны иметь такое же количество звонков, которое хотите удалить, так же, как и звонки на новые.

6 голосов
/ 11 июня 2009

Вам понадобится одно удаление для каждого нового в обратном порядке новых.

4 голосов
/ 11 июня 2009

Вам нужно прочитать это: http://isocpp.org/wiki/faq/freestore-mgmt#multidim-arrays

В двух словах, выделите матрицу в виде одного куска, если он прямоугольный:

int* matrix = new int[3*3];

for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j)
        matrix[i*3+j] = x;

delete [] matrix;

Поскольку он размещен в одном чанке, его также можно удалить в одном чанке.

Или вы можете сделать что-то похожее на то, что вы делаете, но сделать выделение для каждой строки. Обязательно сначала удалите каждую строку, а затем матрицу.

В связанной статье также есть информация о том, как обернуть неприятные объекты указателя / массива в классе.

1 голос
/ 13 июня 2009

Массив указателей может быть ненужным. Вы можете просто выделить одномерный массив из 9 элементов и выполнить математику для преобразования двумерных индексов в одномерные.

Помимо обмена delete[] операциями, вы должны учитывать, что происходит при сбое выделения. Если при втором выделении выдается std::bad_alloc, ваша программа теряет память из первого выделения. Правильно написанный класс матрицы (как предложил Фред Ларсон) будет обрабатывать освобождение памяти для вас.

0 голосов
/ 11 июня 2009

Каждый элемент в матричном массиве - это int [], в дополнение к этому, сама матрица - это массив int * (int * []), принимая во внимание эти правила, вы должны выполнить

delete [] matrix [i] {i = 0,1,2}

а потом делай delete [] matrix для удаления самой матрицы.

Надеюсь, это поможет. Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...