| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > работа с трехмерными массивами |
| Автор: ElKa 12.9.2010, 18:24 |
| подскажите пожалуйста как лучше организовать работу с трехмерными массивами с С++ я только начала работать, еще многого не знаю надо написать программу, обрабатывающую информацию о трехмерных объемах т.е. надо будет в трехмерных, двумерных и одномерных массивах сохранять данные и постоянно с ними оперировать вопросы такие - стоит ли создавать классы для массивов и операторы в них для более удобной обработки, напр. оператор присваивания массива и т.д. и классы Array3, Array2, Array - как декларировать указатель на трехмерный массив и инициализировать сам массив - как удалять многомерные массивы? так же, как и одномерные? delete [] p.. - если трехмерные массивы могут иметь две размерности, а операции с ними одни и те же, как лучше с ними работать? |
| Автор: vnf 12.9.2010, 19:38 | ||||||||
Стоит, очень стоит
Как указатель на объект класса массива CMySuperArray * superarray = new CMySuperArray(5,5,8);
delete superarray
можно трактавать двухмерный массив как частный случай трёхмерного у которого одна из размерностей 1 можно трактавать одномерный массив как частный случай трёхмерного у которого две из размерностей 1 т.е. достаточного одного класса трехмерного массива реализовать такой класс можно попробовать с помощью vector |
| Автор: ElKa 19.9.2010, 23:30 | ||||
| vnf, спасибо! что-то я не разберусь с этими массивами мне нужен класс для массивов, в котором можно будет размерность устанавливать я написала темплейт и почему-то ошибки посмотрите пожалуйста array.h
array.cxx
вот здесь ошибка Array &Array<T,s1,s2,s3>::operator=(Array &right) говорит expected constructor, destructor, or type conversion before '&' token и еще вопрос как мне декларировать и создавать объекты этого класса в других классах? Array [][][] arr; int arr[2][3][5]; |
| Автор: vnf 20.9.2010, 07:19 | ||||||||||
должно быть
то что в угловых скобках является неотемлимой часть имени класса соответственно при использовании класса
Вопрос: у вас везде будут испоьлзоваться массивы одинаковой размерности? Если нет, то размерности лs1 s2 s3 лучше не включать в праметры шаблона, а сделать аргументами конструктора
использование
ещё вашему классу нехватает деструктора, в котором нужно будет освобождать память delete [] a_ |
| Автор: ElKa 20.9.2010, 22:12 |
| vnf, спасибо, сейчас все внедрю и посмотрю, что будет |
| Автор: Master01 20.9.2010, 22:44 | ||
| Если это не учебный проект, цель которого именно в том, чтобы "научится создавать собственные трёхмерные массивы", а вам просто нужен в вашей программе трёхмерный массив, то можете воспользоваться готовой реализацией - boost::multi_array вот пример из хелпа
Добавлено через 5 минут и 19 секунд однако ничего так код для человека, который "с С++ я только начала работать, еще многого не знаю" |
| Автор: ElKa 21.9.2010, 21:48 | ||||
| Master01, спасибо, этот вариант тоже попробую.. а проект не учебный, а очень сурьезный опять ошибка у меня.. посмотрите пожалуйста пока код выглядит так array.h
array.cxx
ошибка здесь Array<T>::Array(int s1, int s2, int s3): a_(new T[s1][s2][s3]), _size1(s1), _size2(s2), _size3(s3){} говорит - `s2' cannot appear in a constant- expression - `s3' cannot appear in a constant- expression |
| Автор: vnf 21.9.2010, 22:01 | ||||||
на
здесь
нужно принициализировать i,j,k, иначе на дебажной будет работать а в релизе ошибки посыплются (int i = 0 и т.д.) в setValue и getValue нужен контроль на выход за границы массива |
| Автор: RedDigger 25.9.2010, 02:52 | ||||||
| Прошу прощения что влезаю в данный топик но не легче ли будет использовать обычные динамические массивы.. Создать класс для обработки 3х мерных массивов довольно просто. инициализировать подобные элементы также труда составить не должно. Вот рабочая программка только что наваянная: main.cpp
myarray.h
myarray.cpp
Под линуксом работает нормально.. винды нет для проверки но теоретически работать должна и там.. Возможно изза разных компиляторов может чтото ругаться при сборке но все должно правиться без особого труда.. Надеюсь информация поможет. |
| Автор: ValeryLaptev 25.9.2010, 07:41 |
| Если проект серьезный, как утверждает Elka, то лучше не писать велосипед, а использовать вектор векторов векторов. Из стандартной библиотеки. |
| Автор: RedDigger 25.9.2010, 13:03 | ||
Но при этом не учитывается что вектор занимает в памяти намного больше места нежели обычный массив. А если данных будет очень много??? результатом будет разница в скорости работы.... Холивар поднимать не хочу.. мое дело предложить. |
| Автор: ElKa 25.9.2010, 19:38 |
| RedDigger, спасибо, попробую и так ValeryLaptev, мне нужны именно массивы, потому что слишком много данных |
| Автор: vnf 26.9.2010, 09:07 |
| ElKa Вопрос: на сколько больше памяти занимает vector по сравнению с массивом? |
| Автор: RedDigger 26.9.2010, 21:38 |
| Вектор - это структурный объект.. У него есть несколько больше возможностей и параметров которые возомжно не нужны в примере.. возможно следует только создать массив, удалить его при выходе и иметь возможность положить туда чтолибо или вытащить с него... Для огромного объема данных приходится иногда изобретать велосипед.. иногда и 28.4 колесный... лично мне не привыкать |
| Автор: JackYF 29.9.2010, 23:09 | ||
Откуда информация? |
| Автор: Master01 30.9.2010, 13:33 |
Вы не совсем правильно понимаете эти результаты. Контейнер будет занимать всегда на N байт больше и это не зависит от количества элементов. Например, если память мне не изменяет, std::vector даже пустой (не содержащий полезных данных) занимает где-то 20 байт. т.о. если говорить, к примеру, о массиве int из 1024 элементов, требующих для хранения (предполагаем что int = 4 байта) 4 Кб, то эти 20 байт уже не кажутся таким кащунственным разбазареванием ресурсов. А лепить что-то своё, ради выйгрыша в 20 байт весьма сомнительно ... а вот политика выделения памяти, которой следует тот или иной контейнер - это действительно то, на что слежует обратить внимание, если нужно что-то оптимизировать. |
| Автор: RedDigger 30.9.2010, 13:36 |
| Не учел... Спасибо за разъеснение. |
| Автор: Леопольд 30.9.2010, 16:29 | ||||
Тут вроде-бы в помощь shared_ptr, но для того что-бы достучаться до элемента, придётся делать как-то так:
Лично мне такой вариант не очень... |
| Автор: JackYF 30.9.2010, 20:50 |
Что-то я не понял, почему трижды. При глубоком копировании вектора векторов векторов векторов ... любой степени вложенности всё копируется единожды. По крайней мере, если вектор == std::vector. Но так должно быть и у любого другого вменяемого вектора. |
| Автор: Леопольд 2.10.2010, 10:03 |
| Я говорил про swap, который повсеместно используется в STL. Он создаёт временную копию. |
| Автор: mes 2.10.2010, 10:20 | ||
я Вас правильно понял, что swap одного вектора в другой медленее чем просто копия ? |
| Автор: ElKa 2.10.2010, 17:25 | ||||||
| RedDigger, а как передавать такие массивы объектам других классов? мне нужно создавать объекты, которые содержат по два трехмерных массива в общем конструктор должен быть такой
и операторы наверное же тоже нужны myarray.h
myarray.cxx
|
| Автор: JackYF 2.10.2010, 21:08 | ||
Я сомневаюсь, что swap двух векторов делает временную копию. Проверяли? |
| Автор: RedDigger 2.10.2010, 21:32 | ||||||||
Лучше всего передовать их по ссылке. В данном случае стек вызовов не переполняется лишними объектами. А внутри класса куда тебе надо завести данные создаешь член класса типа MyArray * (допустим)_b. Но с операторами ты немного намудрила. впринципе могу помочь.. Мои координаты - Skype: sl.spell Mail: pn.spell{at}gmail.com |
| Автор: Леопольд 3.10.2010, 17:01 | ||
|
| Автор: mes 3.10.2010, 17:33 | ||
|
| Автор: ElKa 5.10.2010, 22:54 | ||||
| посмотрите пожалуйста код почему то не те элементы вызываются и зависает ехе массивы 3мерные и что-то я с этими указателями запуталась и еще меня смущает operator [](int i), я его оставила таким же как для одномерных массивов, это правильно? array.h
array.cxx
|
| Автор: Леопольд 6.10.2010, 09:59 | ||||
| ElKa, c двумерными массивами код уже сложно читать, а с тремя измерениями становится совсем тяжко, что чревато багами. Индексы лучше переименовать в column, row, dept (или x, y ,z) во всём коде. Если производительность не критична, то можно попробовать уйти от трехмерных массивов. Например, использовать что-то типа std::map<Point3d, float>. IMHO логика в Array::setValue извращённая, если выход за границы, возвращает true, если всё ОК, возвращает false. Макроса assert в релизе обычно нет (#define NDEBUG). Проверять им что недостаточно памяти не стоит. Использовать malloc a потом delete[], это, по моему уже UB(undefined behaviour). Вместо malloc надо использовать new[]; Вызывает подозрение что на три выделения памяти делается два delete (а не три). Если есть возможность то лучше использовать исключения (или assert, если позволяет специфика приложения) в Array::getValue и Array::setValue. Исключения более универсальны, assert не обработаешь, но зато нет накладных расходов. В Array::operator= утечка памяти. Вместо трёх delete, всего один. И вообще, возникает ощущение что код писали как в мульте "Простоквашино" писали письмо. Строчку ты, строчку твой кот, а всё остальное Шарик...
Возникает ощущение что ты сама его не смотрела. Видимо практикуешь "слепой" десятипальцевый набор с завязанными глазами.. P.S. А может это просто стёб? Бывает и такое. Весьма похоже, надо сказать. |
| Автор: Леопольд 6.10.2010, 12:05 | ||||
Если оно надо, то можно допилить.
http://liveworkspace.org/code/48955ec79fab6268757bc9b65f3aad5f |
| Автор: Леопольд 7.10.2010, 13:39 |
| "допилил"... |
| Автор: ElKa 10.10.2010, 14:36 | ||
ну в общем так и есть, если просмотреть комменты выше, то это должно быть понятно за помощь спасибо, сейчас все внедрю и посмотрю, что будет |