Путем отладки мне удалось найти функцию из-за которой мои герои внезапно удаляются. Ниже приведен код функции в которой это происходит - DummyDealExtraDamage и на всякий случай сверху вставлю функцию отложенного удаления юнита.
Отладка показывает что именно эта функция пытается удалить героя на месте вызова DelayedUnitRemove, хотя туда отчетливо подается dummy и только, причем дамми который был создан пару строчек назад. Как туда мог попасть герой - не понятно.
Баг проявляется отнюдь не всегда, в 1 из 15 случаев примерно. И не у всех персонажей, использующих DummyDealExtraDamage.
Есть какие-то предположения?
	void DelayedUnitRemove(unit u, float time, string fname, string moduleName)
	{
		if (time == 0.00)
		{
			RemoveUnit_s(u, fname, moduleName);
			u = null;
			return;
		}
		timer t = CreateTimer();
		SaveUnitHandle(g_Hashtable, GetHandleId(t), T_UNIT, u);
		SaveStr(g_Hashtable, GetHandleId(t), T_UNIT+1, fname);
		SaveStr(g_Hashtable, GetHandleId(t), T_UNIT+2, moduleName);
		TimerStart(t, time, false, lambda void ()
		{
			timer t = GetExpiredTimer();
			unit u = LoadUnitHandle(g_Hashtable, GetHandleId(t), T_UNIT);
			string fname = LoadStr(g_Hashtable, GetHandleId(t), T_UNIT+1);
			string moduleName = LoadStr(g_Hashtable, GetHandleId(t), T_UNIT+2);
			RemoveUnit_s(u, fname, moduleName);
			DestroyTimer(t);
			u = null;
			t = null;
		});
		t = null;
		u = null;
	}
	
	
	void DummyDealExtraDamage(unit src, unit target, float dmg, int school, bool canBeReturned)
	{
		if (IsUnitDummy(src))
		{
			src = GetDummyOwningUnit(src);
			DummyDealExtraDamage(src, target, dmg, school, canBeReturned);
			src = null;
			target = null;
			return;
		}
		location loc = GetUnitLoc(src);
		unit dummy = CreateDummy(GetOwningPlayer(src), src, loc);
		SetDummyExtraDamage(dummy);
		if (!canBeReturned)
		{
			SetDummyReturnDamage(dummy);
		}
		DummyDealDamage(dummy, target, dmg, school);
		DelayedUnitRemove(dummy, 0.2, "DummyDealExtraDamage", "Dummy");
		RemoveLocation(loc);
		loc = null;
		dummy = null;
		src = null;
		target = null;
	}

Точно больше 100500 утечек нет? Эт хз как же надо было забить хт чтобы такое приключилось?
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
15
PT153:
У DUMMY_OWNER и T_UNIT разные значения?

Я тут пока смотрел, заметил, что ты вообще не чистишь хеш. Ни для таймера уделения, ни для самого даммика. Стоит пока исправить это.
Аргументы функций обнулять не нужно.

Я не вижу ни одной причины, почему тут может удалятся герой. Думал на отсутствие очистки хеша, но ведь после создания таймера ячейка перезаписывается, то есть там хранится уже даммик. Может ты скопипастил и где-то ввёл неверное название функции?
DUMMY_OWNER = 150
T_UNIT = 159
Упс, а хеш-таблицы надо чистить? Не ну это уже совсем дичь. Код захламится на треть очисткой хеш-таблицы. У меня сотни мест где я её использую и не чищу вообще. Ну потому что это уже через чур, и переменные обнулять, и ладно ресурсы удалять, но хеш чистить эт перебор, ненене, работает так и норм. Пусть он в памяти будет толстенный, как-нибудь переживу. Размер на логичность поведения влиять не должен, не 4 гб же там в памяти. Все равно пишет в одни и те же ячейки, перезаписывая.
Я проверил, нигде нет этого названия. Я не копипастил лишнее, баг именно в этой функции.
28
Упс, а хеш-таблицы надо чистить?
Надо. Благо есть такая функция.
native FlushChildHashtable takes hashtable table, integer parentKey returns nothing
Скармливаешь хендл таймера или даммика, и все записанные поля обнуляются.
15
PT153:
Упс, а хеш-таблицы надо чистить?
Надо. Благо есть такая функция.
native FlushChildHashtable takes hashtable table, integer parentKey returns nothing
Скармливаешь хендл таймера или даммика, и все записанные поля обнуляются.
Тогда это всё упрощает, очистку хештейбла запихну в функцию безопасного удаления юнита, и сделаю такую же функцию для таймеров, и можно считать что таблица очищена от лишнего.
28
Было бы неплохо глянуть на тру JASS (то есть уже после обработки cJass) функций, что в шапке.
15
PT153:
Было бы неплохо глянуть на тру JASS (то есть уже после обработки cJass) функций, что в шапке.
Странно, но когда я добавил очистку очистку хеш-таблицы к удалению таймеров и юнитов этот баг перестал появляться)
32
Точно больше 100500 утечек нет? Эт хз как же надо было забить хт чтобы такое приключилось?
Принятый ответ
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.