找回密码
 点一下
查看: 1260|回复: 18

jass运行的问题

[复制链接]
发表于 2009-12-12 21:01:50 | 显示全部楼层 |阅读模式
有一段jass代码 目的是求得一个可用的坐标点  这段代码短时间运行多次就会bug 求原因 及解决方案



首先随机在地图上找个点
如果这个点的地面可通行=false 或者 在某3个区域内
就从全局变量里预设好的23个点 里选一个
返回该点

function getRandomLoc takes nothing returns location
    local location nub = GetRandomLocInRect(GetPlayableMapRect())
    if (RectContainsLoc(gg_rct_RandomF1,nub) == true or RectContainsLoc(gg_rct_RandomF3,nub) == true or IsTerrainPathableBJ(nub, PATHING_TYPE_WALKABILITY) == true  or RectContainsLoc(gg_rct_BossArea,nub) == true) then
        
        set nub = udg_birthPoint[GetRandomInt(1, 23)]
        call DisplayTimedTextToPlayer( Player(0), 0, 0, 10.00, ( "getRandomLoc()修正为:X" + ( R2S(GetLocationX(nub)) + ( ",Y" + R2S(GetLocationY(nub)) ) ) ) )
    endif
    return nub
endfunction

少量运行还正常  短时间运行多次 貌似会无法返回正确的点
用消息看 该点  x=0.00... y=0.00

代码里没有"等待"的动作

另外附加:如果一个全局点变量不清理就赋值 会泄露么

总结   
症结:问题是一个点不能多次引用的问题 只能创建新点....
发表于 2009-12-12 21:05:17 | 显示全部楼层
应该是udg_birthPoint里存储的点被清除了。
某些索引对应udg_birthPoint[]的点实例被Remove了(?)。
看起来貌似是这样
回复

使用道具 举报

 楼主| 发表于 2009-12-12 21:09:11 | 显示全部楼层
但是如果少量运行的话 又会恢复正常
回复

使用道具 举报

发表于 2009-12-13 07:32:09 | 显示全部楼层
“另外附加:如果一个全局点变量不清理就赋值 会泄露么”
点本身不清除就会泄露。
全局变量也要set null。
但是和局部变量相比它的泄露就基本无足轻重了,因为这玩意是可以反复使用的。
当然,set null是更好的。

“问题是一个点不能多次引用的问题 只能创建新点....”
这个是不可能的吧…………
应该是LZ在没想到的地方不小心对udg_birthPoint[]进行了操作。
回复

使用道具 举报

发表于 2009-12-13 09:00:12 | 显示全部楼层
楼主的这句set nub = udg_birthPoint[GetRandomInt(1, 23)]需要改成
call RemoveLocation(nub)
set nub = OffsetLocation(udg_birthPoint[GetRandomInt(1, 23)],0,0)
以指定的点做参数来生产新的点而不是指向,以便可以在后面的动作把nub删除,如果只是set nub = udg_birthPoint[GetRandomInt(1, 23)]的话,删除nub就同时删除了udg_birthPoint所指向的点
回复

使用道具 举报

发表于 2009-12-13 09:11:37 | 显示全部楼层
引用第4楼libla于2009-12-13 09:00发表的  :
楼主的这句set nub = udg_birthPoint[GetRandomInt(1, 23)]需要改成
call RemoveLocation(nub)
set nub = OffsetLocation(udg_birthPoint[GetRandomInt(1, 23)],0,0)
以指定的点做参数来生产新的点而不是指向,以便可以在后面的动作把nub删除,如果只是set nub = udg_birthPoint[GetRandomInt(1, 23)]的话,删除nub就同时删除了udg_birthPoint所指向的点

但是LZ说过有些时候是可以的。也就是说,在某些情况下,LZ删除了从这个函数获取的点实例,造成Bug。
但是在另一些情况下,LZ没有删除这个点实例,就没有Bug……

PS:我现在才发现,LZ的nub这个局部变量根本没set null……
回复

使用道具 举报

发表于 2009-12-13 09:15:19 | 显示全部楼层
楼主后面的函数肯定把这个函数获得的点删除了,但是这个函数有2个情况,如果第一次获得的点符合条件,那么就是生成的一个新点,删除没有问题,否则的话nub指向已有的点,后面删除后会导致已有的点也被删除,不能再利用
所以说大量调用才会遇到问题
回复

使用道具 举报

发表于 2009-12-15 09:43:41 | 显示全部楼层
刚学的,现炒一下
p1=L1
p2=L2
p1=p2
会使得L1泄漏,并且使得p1和p2共同指向L2.

楼主你的句子里就有这样的问题。
楼主再设一个点变量用于判断吧,记得清除。
回复

使用道具 举报

发表于 2009-12-15 14:02:27 | 显示全部楼层
L1会泄漏 JASS是这么弱智的吗?
回复

使用道具 举报

发表于 2009-12-15 14:07:28 | 显示全部楼层
是的,jass对于这方面就是这么所谓的弱智……什么都需要coder来做
回复

使用道具 举报

 楼主| 发表于 2009-12-15 18:42:18 | 显示全部楼层
e...感谢地板的指正
情况稍微有些复杂 C语言我也没怎么学 不知道哪里是指针哪里不是

set nub = udg_birthPoint[GetRandomInt(1, 23)]这句上面空了一行 其实就是之前试图使用call RemoveLocation()的 但是发现没有用

另一方面 大量运用以后 返回 x=0.000 y=0.000  的情况也在继续增加(从20%提升到95+%)  但是之后的少量运用情况又出现了连续数次的正常

于是另外总结2点
关于点 尽量使用能生成新点的功能 使用指向会变得麻烦
关于set null的问题 我的整个地图都没有set null 但是退出完全没有卡的感觉 就如同DotA退出一样
回复

使用道具 举报

发表于 2009-12-15 23:03:13 | 显示全部楼层
P1=L1
P2=L2
P1=P2
L1会泄漏。。
那 P1 = null    L1不是也会泄漏吗。。
回复

使用道具 举报

 楼主| 发表于 2009-12-16 13:45:48 | 显示全部楼层
..... set P1=null之前要 call RemoveLocation的啊 常识
回复

使用道具 举报

发表于 2009-12-16 14:11:50 | 显示全部楼层
使用销毁函数后 handle不需要set null  数据已经被销毁了 你对handle做点啥一点意义也没有
回复

使用道具 举报

发表于 2009-12-16 15:07:48 | 显示全部楼层
这个是jass弱智的地方,你如果只是用函数销毁而不去set null的话,对于这个handle的引用计数仍然存在,这个handle就永远不会被重用
而如果你set null了,那么引用数就会减少
如果一个handle本身为空且没有引用,它才能够被重用

所以光是set null和光是清除销毁都是不够的
回复

使用道具 举报

发表于 2009-12-16 15:28:52 | 显示全部楼层
我上次就做过类似的测试 调用了销毁函数足以  下面是循环创建5个点 然后RemoveLocation 没有set null
Not Set Null.jpg
回复

使用道具 举报

发表于 2009-12-16 15:31:11 | 显示全部楼层
你的测试是基于什么的?全局变量还是局部变量?
回复

使用道具 举报

发表于 2009-12-16 17:44:43 | 显示全部楼层
引用第15楼hunluan89于2009-12-16 15:28发表的  :
我上次就做过类似的测试 调用了销毁函数足以  下面是循环创建5个点 然后RemoveLocation 没有set null

就这个测试图片来说:
我想问问,在前面创建的6个点中,1048674和1048675的HandleId在第二次测试时被重用了吗?
1048673-1048669被重新使用了。
而最后一个创建的点的HandleId为1048676,是一个新出现的Id。
由此我想可以推出1048674和1048675这两个HandleId没有释放成功。
回复

使用道具 举报

发表于 2010-1-11 13:48:14 | 显示全部楼层
嗯楼上都说得对
这问题 一定是你把全局变量的点清除
触决办法是不是直接传给他
而是重新以那个点为村准COPY一个点出来(重新创建的意思)--这个时间就记把那个随机的坏点Remove掉 不然就多了一个无用的点
这样就不会出现假handle指针了
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-7-22 08:27 , Processed in 0.046356 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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