Другие языки программирования и технологии

Динамический массив С++

Появилась надобность удалять не весть массив (3-х мерный причём) ,а только некоторые элементы. Вот на примере двумерного массива (Xp и Yp это его размеры)
unsigned short** DATAmap;
DATAmap = new unsigned short*[Xp+1];
for (unsigned short i = 0; i < Xp+1; i++)
DATAmap[i] = new unsigned short[Yp+1];
как мне удалить например DATAmap[2][2] ? вот только его
Oleg Marincenco
Oleg Marincenco
531
А что должно произойти с остальными элементами массива, если удалить один из них?

Должны ли они оставаться на своих местах либо сдвигаться плотнее?

Ещё один вопрос: какой прок от удаления отдельных элементов массива? Много ли памяти можно вернуть системе, и сто́ит ли такая экономия затрат машинного времени?

Моё субъективное мнение: лучше не заниматься удалением по-отдельности, а просто помечать элементы как удалённые. В любой функции, где осуществляется обход массива по элементам, прежде всего следует обращать внимание на пометку: „удалённые” элементы просто игнорировать. Ну а если очень хочется, то отдельно можно написать функцию реального уплотнения массива, которая будет сдвигать элементы, выбрасывая помеченные. И вызывать такую функцию исключительно по крайней нужде.

Вениамин, просто создайте параллельно ещё один массив, так называемый массив размещения (allocation array). Это будет булевский массив той же размерности и того же размера, что и массив данных. В блоке инициализации массива данных также необходимо проинициализировать массив размещения (например, значением True). Тогда операция удаления отдельного элемента сведётся к смене значения соответствующего элемента в массиве размещения.
ДВ
Дмитрий Войнов
16 172
Лучший ответ
Дмитрий Войнов Гм, гмм...

Интересно, трехмерный массив это что, куб данных?
Дмитрий Войнов ВЕНИАМИН!!! Да у Вас указатель на указателе!!!

Зачем Вам тратить машинное время, выделяя память под отдельные подструктуры?

Лучше, объявите не-динамический массив указателей, выделите память для данных одним блоком в динамической области памяти и просто распланируйте указатели на выделенный блок памяти. В таком случае удаление отдельного элемента — это обнуление соответствующего указателя. Главное, не потерять основную ссылку на блок памяти, чтобы по завершении работы можно было вернуть память системе. Может быть так проще?
Дмитрий Войнов Да и с размерами Вы перемудрили.
Если при помощи операции new создаётся массив, то в квадратных скобках указывается реальный размер массива (количество элементов либо подмассивов). В Вашем случае это Xp, Yp.

unsigned short** DATAmap;
DATAmap = new unsigned short*[Xp+1];

можно записать:

unsigned short** DATAmap = new unsigned short*[Xp];
Дмитрий Войнов Вас можно понять. Представленный Вами способ объявления динамического массива — классический, именно его Вам преподавали. Но он не самый оптимальный.

typedef unsigned short* ushortPtr;
ushortPtr anch = new unsigned short [Xp*Yp];
ushortPtr DATAmap [Xp][Yp];
for (int i = 0; i<Xp; i++)
 for (j = 0; j<Yp; j++)
  DATAmap [i][j] = anch [i*Xp+j];
Дмитрий Войнов Понимаю, что от такого объёма информации у кого угодно голова кругом пойдёт.
Последние замечания:
1) Если уже после условного удаления элемента вдруг потребуется присвоить ему значение, то в обязательном порядке в первую очередь восстанавливаем указатель, а уже потом присваиваем. Стараемся не забывать формулу соответствия между трехмерным и одномерным массивами.

✓ DATAmap [i][j][k] = anch [(i*Xp+j)*Yp+k];

2) Возможен случай, когда при выполнении операции new система не нашла подходящий блок памяти. В этом случае ничего не выделяется, а операция new возвращает значение NULL. Саму возможность такого случая необходимо держать под контролем. Ведь при попытке использования указателя, который в действительности адресует пустоту, возникнет ошибка времени выполнения.

ЭТО ВСЁ.
Oleg Marincenco я просто стал модифицировать свою симуляцию экосистемы, и там существа могут брать и РАЗМНОЖАТЬСЯ!!! Ранее их было фиксированное кол-во и при смерти одного сравнился другой с мутациями, а теперь если 1 умирает, или рождается, то меняется размер памяти.
Впринципе, я посчитал, более 0.5 гига памяти они не сожрут, когда как карта 10к на 10к (12 байт на клетку) жрёт более гига, т. ч. пойдёт условное обозначение свободных клеток (например указать объект просто 0, чтобы его симуляция не обрабатывала программно). За информацию об указателях спасибо!
Так а в чём проблема, идёшь по циклу удаляешь элементы [2][2][i], освобождаешь память
Еще один пытается гланды через задницу удалять.
СПИСКИ есть для этого.
=)

Алгоритмику элементарную надо знать.

При программировании реальных задач, массивы используются довольно редко.
В основном как перечислимые типы.
Они очень быстрые, но совершенно не гибкие по своей структуре.
Юра Клюевский
Юра Клюевский
15 350
Oleg Marincenco ой, быррр.... это же структура, там невыровненные данные и прочее... нененене, там ещё ограничение на кол-во доступных элементов