Очистка после динамически назначенного многомерного массива

0

Итак, я динамически присваивал память двумерному массиву:

int **paMatrix = new int*[r];

for(int i=0; i<r; i++)
    paMatrix[i] = new int[c];

Предположим, что мой код уже определен r и c. Теперь я хочу снова освободить память. Если paMatrix был paMatrix, delete[] paMatrix; будет достаточно. Это также достаточно в этом случае, или мне нужно написать

for(int i=0; i<r; i++)
    delete[] paMatrix[i];

delete[] paMatrix;

В случае, если мне нужно вызвать delete один раз для каждого new оператора, есть ли способ переписать мой код, так что мне нужен только один оператор delete?

  • 2
    Вы должны удалить всех участников. Кроме того, у вас нет 2D-массива, у вас есть указатель на указатели (и именно поэтому одного удаления недостаточно).
  • 2
    у тебя слишком много звезд, чтобы назвать это примером C ++
Показать ещё 7 комментариев
Теги:
arrays
pointers
memory-management
dynamic-memory-allocation

4 ответа

3
Лучший ответ

В общем, вам нужно сопоставить каждое new с delete поэтому, если вы здесь жёстко манипулируете целым массивом необработанных указателей, вам действительно нужно будет удалить их по очереди.

Это может быть серьезной проблемой, если код между new и delete не является простым, и почти невозможно гарантировать, может ли он генерировать исключения. По этой причине вы должны всегда использовать типы RAII, такие как контейнеры и интеллектуальные указатели, для управления динамическими ресурсами. В этом случае vector<vector<int>> может быть подходящим выбором.

Я предполагаю, что реальный вопрос: "Что делает delete и delete[] действительно за сценой?"

Если тип объекта имеет нетривиальный деструктор, он вызывает деструктор на каждом объекте до освобождения памяти. Таким образом, типы RAII будут автоматически освобождать любой ресурс, который они управляют, через своего деструктора; но исходные указатели не имеют деструкторов, поэтому их удаление не освободит память, на которую они указывают.

3

Как уже говорилось, в c++ у одного редко бывает более одной косвенности через указатели. На самом деле, в c++ указатели избегают, когда это возможно.

В случае, если мне нужно вызвать delete один раз для каждого нового оператора, есть ли способ переписать мой код, так что мне нужен только один оператор удаления?

Один из способов:

int *paMatrix = new int[r*c];

но тогда вам нужно играть с индексами.

Еще одно решение (без указателей) без какой-либо одной инструкции delete - использовать std::vector:

std::vector< std::vector< int > > paMatrix( r, std::vector< int >( c, 0 ) );
1

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

Однако, если вы захотите изменить свою концепцию массива 2d, вы можете значительно упростить ее. Например, если это действительно матрица размера rxc, вы можете выделить ее как один массив из числа r * c:

int* paMatrix = new int[r*c];

Затем вы сможете удалить его за один шаг.

Компромисс должен был бы индексировать массив, используя нечто вроде paArray[x+c*y] вместо более естественного paArray[x][y].

1

Тебе нужно

for(int i=0; i<r; i++)
    delete[] paMatrix[i];

delete[] paMatrix;

Там нет пути, кроме умных указателей и т.д.

  • 0
    Или, иначе говоря, есть обходной путь: умные указатели и т.д.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню