Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / [C++] Управление памятью (6 стр)

[C++] Управление памятью (6 стр)

Поделиться
Advanced: Тема повышенной сложности или важная.
Страницы: 13 4 5 6 7 8 Следующая »
TruthfinderПостоялецwww5 дек. 201716:07#75
Dmitry_Milk
> с контролем времени жизни во время компиляции

Не будет этого в плюсах.

The PlayerУчастникwww5 дек. 201721:36#76
Dmitry_Milk
> То есть, какая-то конструкция, которая бы позволяла передать объект, адресуемый
> unique_ptr, из скоупа-владельца в какие-то другие долгоживущие скоупы, чтоб там
> можно было временно попользоваться этим объектом (но не дольше, чем врямя жизни
> unique_ptr в скоупе-владельце).
Да. Сырой указатель называется.

> - просто автоматическое приведение unique_ptr к указателю. Но в "/// .... Do
> something" может оказаться что угодно, в том числе и сохранение указателя в
> поле какого-то долгоживущего объекта (возможно не непосредственно в самой
> function, а где-то в глубинах стека вызовов).
Ну если такое случается, то это уже не unique, а shared.

Правка: 5 дек. 2017 21:37

loysoПостоялецwww6 дек. 201713:40#77
Dmitry_Milk
> А в современном C++ со всеми этими unique_ptr и shared_ptr есть какая-то
> аналогия Rust-овского понятия заимствования ссылки? То есть, какая-то
> конструкция, которая бы позволяла передать объект, адресуемый unique_ptr, из
> скоупа-владельца в какие-то другие долгоживущие скоупы, чтоб там можно было
> временно попользоваться этим объектом (но не дольше, чем врямя жизни unique_ptr
> в скоупе-владельце).
Ты все правильно написал. Move semantics - это ровно оно и есть.
Цепочка начинается с std::make_unique, а далее аннотирована std::unique_ptr у calee и std::move у callers.
https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers

Правка: 6 дек. 2017 13:41

loysoПостоялецwww6 дек. 201714:05#78
Dmitry_Milk
> просто автоматическое приведение unique_ptr к указателю. Но в "/// .... Do
> something" может оказаться что угодно, в том числе и сохранение указателя в
> поле какого-то долгоживущего объекта (возможно не непосредственно в самой
> function, а где-то в глубинах стека вызовов).
weak_ptr на unique_ptr, понятно нет.
Было много забавных предложений но они не прошли:
http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3840.pdf
loysoПостоялецwww6 дек. 201714:46#79
Dmitry_Milk
> аналогия Rust-овского понятия заимствования ссылки?
Справедливости ради, Rust тоже не умеет контролировать lifetime у heap-объектов (runtime lifetime), какой ты описал.

weak_ptr на unique_ptr можно конечно самодельные сделать (chromium, qt etc), но сама концепция weak_ptr ущербна.
У тебя может быть тысяча инвариантов, где твой m_myWeakRef стал nullptr. И поэтому владелец m_myWeakRef типично хочет знать не только ПОЧЕМУ он стал nullptr, но и
КОГДА. Поэтому observers - они и в C++, и в Java/C# (занулить ссылку), и в Rust.

Для кастомных runtime игровых heap-объектов проблему можно решить bidirectional ссылками в графе (объектов же). Удаляем вершину - оповещаем заинтересованных соседей.
Они реагируют там как-то. Сам процесс похож на удаление ноды из двухсвязного списка, с уведомлением соседних нод.

Правка: 6 дек. 2017 14:48

loysoПостоялецwww6 дек. 201715:30#80
Dmitry_Milk
Т.е.:
Box<T> - это std::unique_ptr
Arc<T> - это std::shared_ptr (thread safe)
Rc<T> - это условные "самодельные" RefPtr или scoped_refptr (НЕ thread safe. Попутно могут нести интрузивный RC)
-Eugene-Постоялецwww6 дек. 201717:23#81
loyso
> сама концепция weak_ptr ущербна
Лолчто?
WeakPtr - это естественный аналог сырого указателя, только нормальный. Который не становится в рандомный момент висящим, а честно зануляется.
Если бы не накладные расходы, использовал бы его вообще везде.
А сейчас я использую его везде, где время жизни не очевидно (хранится внешний сырой указатель).
innuendoПостоялецwww6 дек. 201717:29#82
loyso
> но сама концепция weak_ptr ущербна.

вообще или в C++ ?

loysoПостоялецwww7 дек. 20173:12#83
innuendo
> вообще или в C++ ?
Разумеется, weak_ptr (как и любая низкоуровневая идиома) имеет право на жизнь.
Но одно дело, когда у тебя всего одно ветвление if (!m_myWeakRef), и другое - когда у тебя весь код ими утыкан
и ты сохраняешь копии предыдущих состояний переменных, чтобы косвенно выяснить события которые произошли (и их аргументы).

Часто если у тебя есть указатель на объект, то ты заинтересован в _изменениях_ данных того объекта (сообщениях, уведомлениях с параметрами).
Ну а если ты подписан на уведомления вообще, то "я удаляюсь" - это лишь одно из уведомлений.
Программисту Васе добавлять уведомление легко (если уже подписан), менять ptr на подписку - лениво и сложно.

Еще пример - weak_ptr жестко завязан на удаление памяти объекта.
В расширяемом коде ты можешь отсоединять подграф объектов от одного графа и цеплять его к другому графу
(гиперграф объектов эдакий).
Т.е. weak_ptr жестко прошит на сценарий remove-and-delete. И к remove-here-and-add-there он не готов.
Разделить отписку-подписку-смерть бывает полезно для расширяемости.

weak_ptr - это такой узкий вырожденный случай, который часто превращается в missuse.

Правка: 7 дек. 2017 3:12

ZefickПостоялецwww7 дек. 20177:55#84
Стас
> Весь этот код это "Инструкция как делать дедлоки".
  Приведи пример хоть одного, который можно получить с помощью этого кода. Если это инструкция, то должно быть не сложно.
TruthfinderПостоялецwww7 дек. 20179:15#85
Zefick
> Приведи пример хоть одного, который можно получить с помощью этого кода. Если
> это инструкция, то должно быть не сложно.

Зачем? Толковым пацанам очевидно. Кому не очевидно пусть страдает и ... учится. Опыт - сын ошибок трудных.

Правка: 7 дек. 2017 9:15

ZefickПостоялецwww7 дек. 20179:24#86
Truthfinder
> Толковым пацанам очевидно
  Пока я вижу, что "толковые пацаны", даже не знают необходимых условий для возникновения дедлока и видят их везде, где есть мьютекс. Печально, что даже программисты на крестах настолько деградировали. Сначала невозможность осилить алгоритмы STL, а теперь ещё и это.
TruthfinderПостоялецwww7 дек. 20179:27#87
Zefick
> Пока я вижу, что "толковые пацаны", даже не знают необходимых условий для
> возникновения дедлока и видят их везде, где есть мьютекс.

Толковые пацаны уже для себя всё доказали. Спорить смысла нет, а доказывать уже нет необходимости. Можешь считать, что ты прав, и дедлока там не будет. Ну и остальные крестописатели тупые. Не вопрос вообще.

cPtr отличный. Так писать самое то.

Правка: 7 дек. 2017 9:27

TruthfinderПостоялецwww7 дек. 20179:34#88
Многолетние войны на ГД показали, что что-то доказывать порой бесполезно. В лучшем случае получишь в ответ: "а, ну да", или "да, ну и пофиг [что ты был прав]". Профит от споров сильно сомнительный. Так что пишите как нравится. Полезный опыт будет.

P.S. В каком-нибудь Яндексе за такой код прогонят как котёнка веником.

SuslikМодераторwww7 дек. 20179:43#89
Zefick
например, здесь:
  cPtr Move() { mt->lock(); cPtr<T> buf(obj); *count = 0; obj = nullptr; mt->unlock(); return buf; };

автор мало того, что теоретически создаёт два одновременно существующих в памяти экземпляра с одним мьютексом, он ещё может вызывать перегруженный конструктор с этим же самым мьютексом:
    cPtr(cPtr *oper) { oper->mt->lock(); obj = oper->obj; count = oper->count; mt = oper->mt; oper->mt->unlock(); };

в случае, если T* == cPtr*. или в деструкторе:
   ~cPtr() { mt->lock(); if (*count > 0) { *count--; if ((*count == 0) && (obj != nullptr)) delete obj; } mt->unlock(); };

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

Правка: 7 дек. 2017 9:49

Страницы: 13 4 5 6 7 8 Следующая »

/ Форум / Программирование игр / Общее

Тема закрыта.

2001—2017 © GameDev.ru — Разработка игр