Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамические массивы динамических массивов 
:(
    Опции темы
TarasProger
Дата 14.8.2015, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Есть класс. Пусть его зовут TItem. Есть другой класс, пусть его зовут TRow и класс этот имеет поле Items тип которого - указатель на TItem. Третий класс по имени, например, TPlane, имеет поле Rows, тип которого - указатель на TRow. В конструкторе TPlane по Rows выделяется память для массива с базовым типом TRow, при этом по Items каждого элемента требуется выделить память для массива с базовым типом TItem. Правильно ли будет написать: 
Код
Rows=new TRow [n];
if (Rows!=nullptr)
{
 LastRow=Rows+n-1;
 for (Row=LastRows; Row>=Rows; --Row)
 {
  Row->Cells=new TCell [m];
  if (Row->Cells==nullptr)
  {
   for (++Row; Ros<=LastRow; ++Row)
   {
    delete [] Row->Cells;
   }
   Rows=nullptr;
   Cont =0;
   return;
  }
 }
}
? Иметь в TRow открытый метод, меняющий количество элементов, не желательно.

Это сообщение отредактировал(а) TarasProger - 14.8.2015, 18:02
PM MAIL   Вверх
feodorv
Дата 14.8.2015, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(TarasProger @  14.8.2015,  18:01 Найти цитируемый пост)
Правильно ли будет написать

Критерии правильности зачастую сильно субъективны. Лично я так бы не написал.


Приведённый код излишне сишный. Особенно проверки на nullptr. В современном мире new бросает исключение при невозможности выделить память, а nullptr никогда не возвращается:
Цитата
Это устраняет необходимость явной проверки результата выделения.



Проблема возникла из-за того, что n и m - нефиксированы в программе, а в классе TRow очень не хочется хранить размер массива TCell? Или по какой-то другой причине?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 14.8.2015, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



В принципе, в таких случаях обычно делают так:
Код
TRow **Rows=new TRow *[n];
for( int i = 0; i < n; ++i) Rows[i] = new Row( ...params... );

Аналогично удаление массива.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
TarasProger
Дата 15.8.2015, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Цитата(feodorv @  14.8.2015,  20:48 Найти цитируемый пост)
Приведённый код излишне сишный. Особенно проверки на nullptr. В современном мире new бросает исключение при невозможности выделить память, а nullptr никогда не возвращается:
Бросило оно исклюкаку. Дальше что? Бросить объект как попало? Начать его чистуку? Откуда? Как? Ладно ещё стояла бы задача обработать в вызывающем кода ошибку в функции, вызванной из вызванной. Тогда исключения адекватны. А когда ошибка ловится в месте возникновения, то большей пакости нет, чем исклюкака, искусственно уводящая обработку ошибки в даль от места её возникновения и выбрасывающая информацию об этом самом месте.

Добавлено @ 10:24
Цитата(feodorv @  14.8.2015,  20:48 Найти цитируемый пост)
Проблема возникла из-за того, что n и m - нефиксированы в программе,
А ничего, что я их отпускать то и не умею?

Добавлено @ 10:27
Цитата(feodorv @  14.8.2015,  20:48 Найти цитируемый пост)
а в классе TRow очень не хочется хранить размер массива TCell?
Он там и хранится. Просто массив должен быть строго прямоугольным и ни в коем случае не ступенчатым.

Добавлено @ 10:28
Цитата(feodorv @  14.8.2015,  20:48 Найти цитируемый пост)
Это устраняет необходимость явной проверки результата выделения.
Мешает явной проверке, так будет правильней.


Это сообщение отредактировал(а) TarasProger - 15.8.2015, 10:40
PM MAIL   Вверх
TarasProger
Дата 15.8.2015, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Цитата(feodorv @  14.8.2015,  21:39 Найти цитируемый пост)
В принципе, в таких случаях обычно делают так:
Выделить всёкод C++
1:
2:
    
TRow **Rows=new TRow *[n];
for( int i = 0; i < n; ++i) Rows[i] = new Row( ...params... );

Аналогично удаление массива.
Энто что за абракдабра?

Добавлено через 1 минуту и 38 секунд
Цитата(feodorv @  14.8.2015,  20:48 Найти цитируемый пост)
Критерии правильности зачастую сильно субъективны. 
По-Вашему один и тот же код в зависимости от каких то субъективностей будет вести себя различно? К сожалению на моей планете маги не живут.

PM MAIL   Вверх
feodorv
Дата 15.8.2015, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(TarasProger @  15.8.2015,  10:38 Найти цитируемый пост)
Энто что за абракдабра?

Ну, если Вы не в состоянии понять простых вещей (когда создаётся не массив экземпляров класса, а массив указателей, который затем инициализируется экземплярами класса с вызовом конструктора не по умолчанию), тогда до свидания.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
TarasProger
Дата 15.8.2015, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Цитата(feodorv @  15.8.2015,  13:04 Найти цитируемый пост)
Ну, если Вы не в состоянии понять простых вещей (когда создаётся не массив экземпляров класса, а массив указателей, который затем инициализируется экземплярами класса с вызовом конструктора не по умолчанию), тогда до свидания. 
Ах вот это что! А я то думал, почему указатель двойной. Только что это даёт?

Добавлено @ 13:12
А может здесь maloc поможет? А то всё таки во внутренности другого класса лезть не охота. Как явно вызвать конструтор по указателю?

Это сообщение отредактировал(а) TarasProger - 15.8.2015, 13:20
PM MAIL   Вверх
feodorv
Дата 15.8.2015, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(TarasProger @  15.8.2015,  13:10 Найти цитируемый пост)
Только что это даёт?

Вызов конструктора не по умолчанию.

Добавлено @ 13:23
Цитата(TarasProger @  15.8.2015,  13:10 Найти цитируемый пост)
Как явно вызвать конструтор по указателю

Placement new.

Это сообщение отредактировал(а) feodorv - 15.8.2015, 14:26


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 15.8.2015, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(TarasProger @  15.8.2015,  10:38 Найти цитируемый пост)
По-Вашему один и тот же код в зависимости от каких то субъективностей будет вести себя различно?

Нет. Увы, TarasProger, Вы очень часто демонстрируете непонимание своего собеседника или поставленной задачи, уводя разговор на совсем другие рельсы. Я про поведение одного и того же кода не говорил ни слова. Вы спросили:
Цитата(TarasProger @  14.8.2015,  18:01 Найти цитируемый пост)
Правильно ли будет написать:
Следовательно, речь идёт не об одном и том же коде, а о наиболее понятном, лаконичном (где-то даже красивом) и безошибочном способе написания кода для решения задачи. Восприятие кода по этим критериям, зачастую, является субъективным. Приведённый Вами код - рабочий, следовательно, можно про него сказать, что он "правильный". Тем не менее, глядя на свой код, Вы задались подобным вопросом, значит в нём есть что-то, Вас не устраивающее. Меня же в нём не устраивает всё. От явного ощущения, что это не C++, и до организации классов. И эта моя субъективность имеет, скорее всего, объективный характер - уверен, что данный код мало кому понравится.
 

Это сообщение отредактировал(а) feodorv - 15.8.2015, 13:51


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
disputant
Дата 15.8.2015, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3



Цитата(TarasProger @ 15.8.2015,  10:20)
Бросило оно исклюкаку. Дальше что? Бросить объект как попало? Начать его чистуку? Откуда? Как? Ладно ещё стояла бы задача обработать в вызывающем кода ошибку в функции, вызванной из вызванной. Тогда исключения адекватны. А когда ошибка ловится в месте возникновения, то большей пакости нет, чем исклюкака, искусственно уводящая обработку ошибки в даль от места её возникновения и выбрасывающая информацию об этом самом месте.

new(std::nothrow) вам в помощь.

Все равно обработка нехватки памяти практически всегда сводится к убиению программы...
PM MAIL   Вверх
TarasProger
Дата 16.8.2015, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Цитата(feodorv @  15.8.2015,  13:51 Найти цитируемый пост)
Следовательно, речь идёт не об одном и том же коде, а о наиболее понятном, лаконичном (где-то даже красивом) и безошибочном способе написания кода для решения задачи. Восприятие кода по этим критериям, зачастую, является субъективным. 
Речь была о правильности, а не красивостях.

Добавлено через 3 минуты и 54 секунды
Цитата(disputant @  15.8.2015,  15:00 Найти цитируемый пост)
Все равно обработка нехватки памяти практически всегда сводится к убиению программы... 
С какого перепуго она вообще должна включать в себя убиение проги? Тем более сводиться к нему. Вот смотрите: работаете Вы в проге часов 300 с перерывами на сон и обед, а потом жмёте одну единственную кнопку и хлоп всё закрылось без сохранения и даже не сказало, почему. Вместо того, чтоб написать: "Закройте пару программ для освобождения памяти и повторите попытку".

Добавлено через 5 минут и 9 секунд
Цитата(feodorv @  15.8.2015,  13:51 Найти цитируемый пост)
 Тем не менее, глядя на свой код, Вы задались подобным вопросом, значит в нём есть что-то, есть
 Ага, есть. Не тестируемость.

PM MAIL   Вверх
disputant
Дата 16.8.2015, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3



Цитата(TarasProger @ 16.8.2015,  13:53)
Цитата(disputant @  15.8.2015,  15:00 Найти цитируемый пост)
Все равно обработка нехватки памяти практически всегда сводится к убиению программы... 
С какого перепуго она вообще должна включать в себя убиение проги? Тем более сводиться к нему. Вот смотрите: работаете Вы в проге часов 300 с перерывами на сон и обед, а потом жмёте одну единственную кнопку и хлоп всё закрылось без сохранения и даже не сказало, почему. Вместо того, чтоб написать: "Закройте пару программ для освобождения памяти и повторите попытку".

Почитайте на эту тему Саттера, "Новые сложные задачи на С++", задача 23 (стр. 156-162).

Наши желания не всегда совпадают с нашими возможностями smile
PM MAIL   Вверх
TarasProger
Дата 17.8.2015, 08:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 5.8.2015

Репутация: нет
Всего: нет



Цитата(disputant @  16.8.2015,  21:26 Найти цитируемый пост)
Наши желания не всегда совпадают с нашими возможностями
Вот именно.
Цитата(disputant @  16.8.2015,  21:26 Найти цитируемый пост)
Почитайте на эту тему Саттера, "Новые сложные задачи на С++", задача 23 (стр. 156-162).
При чём здесь какой то Статер? Что, если он в учебной задаче прописал закрытие, то это как то меняет требования к решению реальной задачи? А если он напишет, что при нехватке ширины экрана для вывода строки надо взрывать комп, ты взрывать будешь, или всё таки переностить текст на следующую строку? Если памяти нехватает, то это может быть вызвано множеством причин, в том числе, легко устранимых, выключая использование памяти парой десятков других приложений. И даже если единственная возможность исправить ситуацию - выключить комп и добавить ему физической памяти, то прога всё равно не имеет права убиваться на месте, а должна сначала сказать пользователю, в чём дело, что он не решил, что она просто глючит, а потом ещё предложить сохранить наработатнные данные в файл и даже заняться пока другими делами, для которых столько памяти не нужно, в том числе в той же самой проге, или даже повторить команду с другими параметрами. Например, надо решить дифур в частных производных и дифур этот аппрокисимируется разностной схемой. На сколько часто бить объём? Может быть при адекватном выводе пользователь просто введёт меньшее количество ячеек и ограничится пока более грубым решением. Это он может сделать самостоятельно. А не писать в службу техподдержки: "Ваша прога у меня внезапно упала при нажатии кнопки "рассчёт"" и отсылать обрывок лога, в котором ещё и по недомыслию автора нет количества ячеек. И пока техподдержка будет с этой проблемой разбираться, пользователь уже трижды проапгрейтит память, причём, уже первый апгрейт позволит решать даже с большим количеством ячеек. Но пользователь даже знать не будет, что дело в расходе памяти и пробовать запускать прогу не будет.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0689 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.