找回密码
 点一下
楼主: linzefei

Union Bug 1个需要注意的地方

[复制链接]
发表于 2009-5-4 15:56:12 | 显示全部楼层
对~~楼主的问题产生的原因是~~整个共用空间被定义为handle类型~~所以handle就会对它进行追踪~~

当这个共用空间赋予一个负值的时候~~handle表尝试查询一个负数handle并增加其变量连接数~~自然就导致非法操作~~

而如果共用空间被声明为integer~~那么jass虚拟机会认为该地址是一个integer型数据~~handle表就不会追踪它~~也不会试图进行查询~~于是就不会有问题~~
回复

使用道具 举报

发表于 2009-5-4 16:20:00 | 显示全部楼层
其实我在那个帖子里也说过这类问题了~~
回复

使用道具 举报

发表于 2009-5-5 10:50:21 | 显示全部楼层
好吧
是我提问时欠考虑了
如果是
local udg_location
lcoal udg_i
set udg_location =Location(0,0)
呢?
也就是说
在空间已经被共用后创建的handle的连接数怎么变化呢?
按照头目所说
“而如果共用空间被声明为integer~~那么jass虚拟机会认为该地址是一个integer型数据~~handle表就不会追踪它~~也不会试图进行查询~~于是就不会有问题~~”
那么在共用空间被声明为handle型时
连接数不会增加
那么这个新创建的点的连接数就是0了?

那么它会被自动清空?
自己测试了下
应该是被清空了
[jass]function create takes nothing returns nothing
local location udg_l = null
local integer udg_i = 0
set udg_l = Location(100,1000)
set udg_handle = udg_i
//call TriggerSleepAction( 2 )
call RemoveLocation(udg_l)call DisplayTextToForce(GetPlayersAll(),I2S(H2I(udg_l)))
call DisplayTextToForce(GetPlayersAll(),I2S(udg_handle))
endfunction
[/jass]
如果最后声明的是handle那么会有1个handle泄露(可以用set 0(null)的方法清空)
如果最后是integer则不会
但是终归还是不知道在函数运行中其连接数是多少
不过加上call TriggerSleepAction( 2 )这句后
显示的handle一直是1048672了(等待完成后才运行下次)
而原来是1048672,1048671俩个值轮换着(1048672先出现)
难道TriggerSleepAction也会占用个handle么?

text.w3x

17 KB, 下载次数: 32

测试的图

回复

使用道具 举报

 楼主| 发表于 2009-5-5 12:48:49 | 显示全部楼层
看不明白你的话...下来看看
回复

使用道具 举报

 楼主| 发表于 2009-5-5 13:00:02 | 显示全部楼层
TriggerSleepAction也会占用个handle..

我加上几个等待  handle就会跑到那么高。。。。
回复

使用道具 举报

发表于 2009-5-5 13:05:34 | 显示全部楼层
待解
回复

使用道具 举报

发表于 2009-5-5 13:11:04 | 显示全部楼层
引用第24楼linzefei于2009-05-05 13:00发表的  :
TriggerSleepAction也会占用个handle..

我加上几个等待  handle就会跑到那么高。。。。

别乱说~~出现这种问题肯定是你测试错误~~
回复

使用道具 举报

 楼主| 发表于 2009-5-5 13:21:56 | 显示全部楼层
[jass]function create takes nothing returns nothing
local location udg_l = null
local integer udg_i = 0
local integer i
set udg_l = Location(100,1000)
set i = udg_i
call RemoveLocation(udg_l)
call BJDebugMsg("开始等待 此handle="+I2S(i))
//call TriggerSleepAction(1 )      
call BJDebugMsg("结束等待 此handle="+I2S(i))
endfunction [/jass]

在前1个等待期间 连续按 handle一直递增

text.w3x

22 KB, 下载次数: 21

回复

使用道具 举报

发表于 2009-5-5 13:24:26 | 显示全部楼层
记得有人说过
handle的清空不是立即的
虽然连接数已经为0
但是还会存在一段时间
回复

使用道具 举报

 楼主| 发表于 2009-5-5 13:27:07 | 显示全部楼层
27楼演示 那加了等待 在前个等待期间 连续按handle就一直递增
不加 就很正常的 2个数值变化

刚看 一直是递增到80然后倒着使用之前的..
此点确实了 同类型的handle  回收机制是按栈
回复

使用道具 举报

 楼主| 发表于 2009-5-5 13:29:35 | 显示全部楼层
多个等待 和1个等待一样
估计就类似触发器事件占 handle
等待作用期间才占handle
触发器动作期间才占handle
之后都回收
回复

使用道具 举报

发表于 2009-5-5 13:50:58 | 显示全部楼层
引用第22楼疯人¢衰人于2009-05-05 10:50发表的  :
好吧
是我提问时欠考虑了
如果是
local udg_location
lcoal udg_i
.......

你确定没有写错?~~没把某个integer写成handle?~~

至于你那个交替的问题~~研究下面这两个函数的区别也许会对你有帮助~~其实就是把call RemoveLocation(udg_l)和call TriggerSleepAction( 2 )交换了下位置~~

function create takes nothing returns nothing
local location udg_l = null
local integer udg_i = 0
set udg_l = Location(100,1000)
call RemoveLocation(udg_l)
call TriggerSleepAction( 2 )
call DisplayTextToForce(GetPlayersAll(),I2S(udg_i))
endfunction

function create takes nothing returns nothing
local location udg_l = null
local integer udg_i = 0
set udg_l = Location(100,1000)
call TriggerSleepAction( 2 )
call RemoveLocation(udg_l)
call DisplayTextToForce(GetPlayersAll(),I2S(udg_i))
endfunction
回复

使用道具 举报

 楼主| 发表于 2009-5-5 14:30:05 | 显示全部楼层
综合结论。
1。删除点的handle不是立刻回收而是有延迟性
2。根据触发器事件不同,动作期间会占一定量的handle 动作一旦结束就回收handle
3。不是等待占handle 仍只是触发器占的

测试
1。单独开个ESC触发器开上一堆等待 创建handle时 会发现handle高了很多 对应1个触发器1个handle   (ESC事件可取得触发玩家)
2。如果是每次触发器动作完 再创建handle 会发现和平时都一样 不会出现handle空位
3。删除完handle 加个等待  等待结束后 立刻创建(同1个触发器内) 会发现handle还是被占了
4。删除完handle 加个等待  等待结束后  开个0秒计时器再创建(独立于触发器线程了) 会发现handle不被占了
5。把玩家按ESC事件换成游戏周期事件(玩家事件有个触发玩家占handle) 测试发现handle不再被占用


目前结论及测试手段
回复

使用道具 举报

 楼主| 发表于 2009-5-5 15:01:39 | 显示全部楼层
1.22测试结果和1.20e一样

只要暴雪不发疯 以后版本的测试结果都一样
回复

使用道具 举报

发表于 2009-5-5 18:16:54 | 显示全部楼层
引用第20楼Renee于2009-05-04 15:56发表的  :
对~~楼主的问题产生的原因是~~整个共用空间被定义为handle类型~~所以handle就会对它进行追踪~~

当这个共用空间赋予一个负值的时候~~handle表尝试查询一个负数handle并增加其变量连接数~~自然就导致非法操作~~

而如果共用空间被声明为integer~~那么jass虚拟机会认为该地址是一个integer型数据~~handle表就不会追踪它~~也不会试图进行查询~~于是就不会有问题~~
1.共用空间?
什么意思?
2.该地址?
指的是什么地址?
共用空间的地址?是物理的还是handle的?
3.handle表就不会追踪它~~也不会试图进行查询 代表 被指向的handle的变量连接数-1吗?

好吧……就这么多……以上33楼……每人+1印象~~
回复

使用道具 举报

发表于 2009-5-5 18:30:42 | 显示全部楼层
还有……如果:
[jass]local unit udg_u = ...
local integer udg_i[/jass]
这样,按头目的说法……先运行第一行:udg_u指向的unit的变量链接数+1
然后运行第二行:udg_i引发Union_bug,公用空间变为integer。
handletable不再跟踪此公用空间……
后面就没有代码了(按照头目的说法,不需要任何代码来排泄)

但是…………………………
第一行增加的变量连接数还是增加了…………
这是为啥呢?
还是公用空间变为integer的时候,变量连接数就-1了?

这个是让我很困惑的一件事情…………
回复

使用道具 举报

 楼主| 发表于 2009-5-5 18:44:34 | 显示全部楼层
另外至于如果我硬要问说这个究竟会不会增加变量连接数?~~那么其实你可以自己分析下的~~首先当local udg_location= Location(0,0)执行的时候~~连接数其实是确确实实增加了的~~但是同时~~当下一条语句执行的时候~~两个变化发生了~~
此时增加了连接数
第一个:由于共用空间有了新的初值~~那么显然就不再指向 Location(0,0)对应的表位~~于是该表位变量连接数被清空~~一旦你destroy了那个location~~这个表位就可以复用了~~
此时 清除了连接数
第二个:随着udg_i被声明~~共用空间的性质发生改变~~于是该共用空间的新值(不管是什么,就算udg_i的初值不为空)~~他也不会对handle表产生任何影响~
以后不会再增加连接数


头目前面说了的
回复

使用道具 举报

发表于 2009-5-5 19:10:27 | 显示全部楼层
引用第31楼Renee于2009-05-05 13:50发表的  :


你确定没有写错?~~没把某个integer写成handle?~~

至于你那个交替的问题~~研究下面这两个函数的区别也许会对你有帮助~~其实就是把call RemoveLocation(udg_l)和call TriggerSleepAction( 2 )交换了下位置~~
.......
我确实是忘写了变量类型……先是handle后面是integer……按头目说的
我的意思是如果在共用空间声明为integer时,创建了一个新的handle,那么它的连接数是多少,因为头目说这是连接数不会增加,那么这个handle应该是会在内容释放之后自动清空的……反正就是这时的连接数……
引用第34楼血戮魔动冰 于2009-05-05 18:16 发表的  :


1.共用空间?
什么意思?
2.该地址?
指的是什么地址?
共用空间的地址?是物理的还是handle的?
3.handle表就不会追踪它~~也不会试图进行查询 代表 被指向的handle的变量连接数-1吗?

.......
这个你看unionbug那个帖子吧,后面有的
引用第35楼血戮魔动冰 于2009-05-05 18:16 发表的  :
这样,按头目的说法……先运行第一行:udg_u指向的unit的变量链接数+1
然后运行第二行:udg_i引发Union_bug,公用空间变为integer。
handletable不再跟踪此公用空间……
后面就没有代码了(按照头目的说法,不需要任何代码来排泄)
.......

实际上时在第二个声明后才开始成为共用空间的
第一个声明时,如果有赋值的话,它跟正常的局域变量是一样的
当第二个局域变量被创建时,创建了一个新的内存空间
同时把第一个变量对应的内容(handle值)改成了第二个,相当于同时把两个变量都赋值了
而第一个变量原来的值就会被放在那不会调用,一直占用内存
如果第二个变量没有赋值,那么这块新的内存空间就是空(不是0,是Null)就跟没有赋值一样,同时两个变量都会成为空
回复

使用道具 举报

发表于 2009-5-5 22:15:05 | 显示全部楼层
union bug 这么诡异的?

我有理由进一步拒绝使用这个东西了。。。
回复

使用道具 举报

发表于 2009-5-5 22:25:40 | 显示全部楼层
以上是研究handle的
……
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-11-23 21:08 , Processed in 0.124323 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表