XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Extremator

offline
Опыт: 39,428
Активность:
u != null
Где-то обсуждался вопрос, стоит ли обнулять глобалки, ну мол set u = нет юнита...
set udg_u = null
Я был уверен что это лишнее, так как глобалки уже есть,
и они не могут плодиться так, как к это могут делать локалки...
Ну так вот, я сделал примерно следующее
set udg_u = CreateNUnitsAtLoc( бла-бла )
call RemoveUnit( udg_u )
а далее идут месаги выводящи имя юнита, его макс.хп, и имя его владельца
как не странно - данные я получаю верные, хоть юнит и был удалён...
но если прождать немного времени (например 1 сек), то я получаю пустые строки (что и логично, юнита ведь уже нету).
. . .
Теперь к сути вопроса.
Если я спрошу равен ли юнит u нулю, то мне ответят отрицательно,
хотя имя его, имя его владельца и его хп я получить уже не могу.
if ( udg_u == null ) then
   // вот это не срабатывает
else
   // получаю этот ответ
endif
Вопрос(ы):
- В каком таком интересном положении находится переменная? Раз я и данные с него взять не могу, но и пустоты там нету.
- Верна ли догадка что - переменная хранит некий адрес ссылающийся на того юнита (которого уже нет), но не может получить.никаких данных по ссылке.
- Является ли такое "хранение адреса" своего рода утечкой? Или же юнит убит, а адрес ведёт просто в-никуда?
Старый 30.04.2014, 14:06
DioD

offline
Опыт: 45,134
Активность:
днище...
у меня вопрос, что мешает после удаления юнита обнулить переменную на него?
Старый 30.04.2014, 14:16
Extremator

offline
Опыт: 39,428
Активность:
пенка на глади морской...
Что мешает ответить на вопрос? вместо того что бы задавать свой
Старый 30.04.2014, 14:35
ScorpioT1000
Работаем
offline
Опыт: отключен
11 уровень на сайте, а позорится так.
Читать xgm.guru/p/wc3/w3datatypes про ссылки и как это работает
ScorpioT1000 добавил:

Ссылочные типы handle

И так, что же такое этот вездесущий хендл? Очень просто – это число. Обыкновеннное целое число.
Называют его по-разному – идентификатор, ссылка, дескриптор, указатель, индекс, smart pointer и другие.
Хендл в Jass является указателем на объект в памяти. А конкретнее – это адрес ячейки в специальной хеш-таблице хендлов.
Точная структура этой таблицы не известна, но есть основание предполагать, что она устроена следующим образом:
При создании какого-либо объекта (пусть это будет юнит) в памяти динамически создаётся его структура со всеми нужными полями. В таблице хендлов выделяется один элемент под этот объект, который хранит в себе указатель на объект в памяти и дополнительную информацию. А наш хендл – это адрес этого самого элемента.
Когда мы удаляем юнита, удаляется эта структура в памяти (перейдя по нашему хендлу), но сам хендл (и другие хендлы этого юнита) остается неизменным.
Когда мы обнуляем хендл (присваиваем ему null), объект удаляется из таблицы, а наш хендл (как число) принимает нулевое значение. И опять-же, другие хендлы, которые ссылались на наш объект, остаются неизменны.
» Немного мыслей здесь
ScorpioT1000:
о каком объекте идет речь? destroy уничтожает данные мгновенно, далее объект становится "пустым" - почти все функции работы с ним возвращают фейлд, при этом хендл висит в памяти
потестируй
проверять существование юнита так GetUnitTypeId(u) > 0 итема GetItemTypeId(u) > 0
+ к этим проверкам добавлять and IsUnitAlive (ну это не точно так, но суть ясна), если мертвые тоже не нужны
Darklight:
ScorpioT1000, Проверил. Да, ScorpioT1000, ты прав! Если юнит не разлагается, то сразу же как умирает (поистечение времени смерти в параметрах юнита) значение в ячейки Хеш таблицы сразу же принимает значение null. ТО есть, ссылки из Хеш таблицы не учитываются. Вернее, после проведения более точного эксперимента, значение юнита в Хеш таблице сразу же обнолвется на null (не очищается, а заменяется значением null) после обработки гибели юнита (если он не разлагается; для разлагающихся - это произойдёт после разложения; или при вызове функции RemoveUnit), приэтом я специально оставил ссылку на юнита в отдельной переменной - так вот там юнит стал "безымянным", но id сохранился - значит варик сам обрабатывает ячейки Хеш таблицы с уничтожаемыми объектами и присваивает им значение null, несмотря на то, что на эти объекты могу быть ссылки из других переменных. И это даже без вызова RemoveUnit
Значит операться на ссылки в хеш таблицах как на источники ключей нельзя :( придётся отдельно сохранять числовые ключи идентификаторов этих ссылок
Ну, или использовать (там где можно) событие "Unit die" и обрабатывать умершего юнита до того как его ссылкав Хеш таблице превратится в null
Вот такая вот засада вышла!
Оригинал: xgm.ru/forum/showthread.php?t=56047
Именно поэтому, после работы с объектом, его надо не только удалять, но и обнулять все хендлы, ссылающиеся на нашего юнита. Если этого не сделать, они будут "висеть" в таблице хендлов и не только засорять память, но и замедлять скорость доступа к этой таблице.
Исключение – локальные переменные, которые являются параметрами функции. Они удаляются автоматически после выхода из функции.
Старый 30.04.2014, 14:37
Extremator

offline
Опыт: 39,428
Активность:
ScorpioT1000:
11 уровень на сайте
фикция же
Старый 30.04.2014, 14:45
ScorpioT1000
Работаем
offline
Опыт: отключен
Регистрация: 13.09.10
2014
Старый 30.04.2014, 14:47
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 12:00.