Подтвердить что ты не робот

Почему "delete [] []... multiDimensionalArray;" оператора в С++ не существует

Мне всегда было интересно, есть ли оператор для удаления многомерных массивов на стандартном языке С++.

Если мы создали указатель на одномерный массив

int *array = new int[size];

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

delete [] array;

Это здорово. Но если у нас есть два размерных массива, мы не можем сделать

delete [][] twoDimenstionalArray;

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

Может кто-нибудь объяснить, почему?

4b9b3361

Ответ 1

Технически, в С++ нет двухмерных массивов. То, что вы используете в качестве двухмерного массива, представляет собой одномерный массив, каждый из которых является одномерным массивом. Поскольку он технически не существует, С++ не может его удалить.

Ответ 2

Потому что нет способа вызвать

int **array = new int[dim1][dim2];

Все новости/удаления должны быть сбалансированы, поэтому нет смысла использовать оператор delete [][].

new int[dim1][dim2] возвращает указатель на массив размером dim1 типа int[dim2]. Таким образом, dim2 должна быть константой времени компиляции. Это похоже на распределение многомерных массивов в стеке.

Ответ 3

Причина delete вызывается несколько раз в этом примере, потому что new также вызывается несколько раз. Удалить нужно вызывать для каждого нового.

Например, если я выделяю 1 000 000 байт памяти, я не могу впоследствии удалить записи с 200 000 до 300,00, он был выделен как один цельный фрагмент и должен быть освобожден как один цельный фрагмент.

Ответ 4

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

Когда вы выделили свой двумерный массив, вы действительно создали N одномерных массивов. Теперь каждый из них должен быть удален, но система не знает, сколько из них есть. Размер массива верхнего уровня, т.е. Массив указателей на ваши массивы второго уровня, аналогичен любому другому массиву в C: его размер не сохраняется системой.

Следовательно, нет способа реализовать delete [][], как вы описываете (без значительного изменения языка).

Ответ 5

не уверен в конкретной причине с точки зрения дизайна языка, я предполагаю, что это имеет какое-то отношение к тому факту, что при распределении памяти вы создаете массив массивов, и каждый из них нужно удалить.

int ** mArr = new int*[10];
for(int i=0;i<10;i++)
{
   mArr[i]=new int[10];
}

my С++ ржавый, я не уверен, что это синтаксически правильно, но я думаю, что он близок.

Ответ 6

Хотя все эти ответы актуальны, я попытаюсь объяснить, что ожидалось, что-то вроде delete[][] array; может работать на динамически распределенных массивах и почему это невозможно:

Синтаксис int array[ROWS][COLS];, разрешенный на статически распределенных массивах, - это просто абстракция для программистов, которая на самом деле создает одномерный массив int array[ROWS*COLS];. Но во время процесса компиляции (когда размерность COLS и ROWS должна быть константой по стандарту), компилятор также запоминает размер этих измерений, которые необходимы для более поздних элементов адреса, используя синтаксис, например. array[x][y] = 45. Компилятор, получивший название этого размера, заменит [x][y] соответствующим индексом на одномерный массив, используя простую математику: [COLS*x + y].

С другой стороны, это не относится к выделенным массивам динамически, если вам нужна одна и та же многомерная функциональность (на самом деле обозначение). Поскольку их размер может быть определен во время выполнения, они должны будут помнить размер каждого дополнительного измерения для последующего использования, а также - и помните, что на протяжении всей жизни массива. Более того, здесь должны быть реализованы системные изменения, чтобы работать с массивами на самом деле как многомерные, оставляя форму [x][y] нотации доступа в коде, не заменяя его одномерным обозначением во время компиляции, а затем заменяя его внутри во время выполнения.

Следовательно, отсутствие of array = new int[ROWS][COLS] не требует необходимости для delete[][] array;. Как уже упоминалось, его нельзя использовать на вашем примере, чтобы удалить ваш "многомерный" массив, потому что ваши вспомогательные массивы (дополнительные измерения) распределяются отдельно (с использованием отдельного вызова new), поэтому они не зависят от верхний массив (array_2D), который содержит их, и все они не могут быть удалены сразу.

Ответ 7

delete [] применяется к любому нескалярному (массиву).

Ответ 8

Вы можете использовать класс-оболочку, чтобы делать все это для вас. Работа с "примитивными" типами данных обычно не является хорошим решением (массивы должны быть инкапсулированы в класс). Например, std::vector - очень хороший пример, который делает это.

Удалить следует вызывать точно, сколько раз вызывается новое. Поскольку вы не можете вызвать "a = новый X [a] [b]", вы также не можете вызвать "delete [] [] a".

Технически это хорошее дизайнерское решение, препятствующее появлению странной инициализации всей n-мерной матрицы.

Ответ 9

Ну, я думаю, что это легко реализовать, но слишком опасно. Легко определить, создан ли указатель new[], но трудно сказать о new[]...[] (если разрешено).