HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Unable to allocate object id/attempt to destroy null struct errors

12-13-2008, 06:00 AM#1
Karawasa
I'm encountering these two errors with a triggered ability. I haven't been able to reproduce it, but I have the error messages in-game. Here is the code, and the image is attached below.

Collapse JASS:
//Implementation: *create an ability based off the item attack speed(gloves of haste)
//                *copy over trigger and config
//Documentation: :)

scope IASAttacking

globals
    private constant integer dum_id = 'A00Z' //ias dummy 1 ability id
    private constant integer max_lvl = 14 //max level for dummy abil
    private constant real duration = 4. //time between attacks to wait before restoring attack speed
endglobals
private struct data
    unit u
endstruct
       
//clear leaks, remove ability after alotted time
private function end_timer takes nothing returns nothing
    local data dat = GetData(GetExpiredTimer())
    local string s = I2S(CS_H2I(dat.u))+"IAS"
   
    call UnitRemoveAbility(dat.u,dum_id)
    call ClearTable(s)
    call dat.destroy()
    call EndTimer(GetExpiredTimer())   
endfunction
//do everything else needed
function IAS_Attacking_Actions takes nothing returns nothing
    local unit u = GetEventDamageSource()
    local string s
    local timer t
    local data dat
    local integer lvl
    local integer id
   
    if GetUnitTypeId(u)==TOWER_ZEAL or GetUnitTypeId(u)==TOWER_FANATIC then
        set id = dum_id
        set lvl = GetUnitAbilityLevel(u,id)
        set s = I2S(CS_H2I(u))+"IAS"
       
        if lvl==0 then
            call UnitAddAbility(u,id)
        elseif lvl<max_lvl then
            call SetUnitAbilityLevel(u,id,lvl+1)
        endif
        //call TextTagUnit(I2S(GetUnitAbilityLevel(u,dum_id)),u,255,0,0,200,.03,2.)
       
        set t = GetTableTimer(s,"timer")
        if t==null then
            set t = GetTimer()
        else
            call EndTimer(t)
            set t = GetTimer()
        endif
        call TimerStart(t,duration,false,function end_timer)
        set dat = data.create()
        set dat.u = u
        call SetData(t,dat)
        call SetTableObject(s,"timer",t)
       
        set t = null
    endif   
   
    set u = null
endfunction

endscope

//==== Init Trigger IAS Attacking ====
function InitTrig_IASAttacking takes nothing returns nothing
    call ORBEngine_RegisterOrb(TOWER_ZEAL, function IAS_Attacking_Actions, "TOWER_ZEAL: IAS attacking")
    call ORBEngine_RegisterOrb(TOWER_FANATIC, function IAS_Attacking_Actions, "TOWER_FANATIC: IAS attacking")
endfunction

Thoughts? Would appreciate any help eliminating error or optimizing trigger.
Attached Images
File type: jpgvjasserror.jpg (822.8 KB)
12-13-2008, 06:50 AM#2
Ammorth
I think this is your problem:

If the unit already has a timer, you remove the timer and create a new one.

The reason why this is a problem:

The data struct that was attached to that timer is now lost and is never destroyed (if the unit attacks again, before the timer expires).

The solution:

Before releasing any timer, make sure the timer has no data attached to it. If there is, destroy it and then release the timer.

What is happening is that you are not destroying the structs, and they keep allocating up to 8190, at which point the struct creation fails, provides the unable to allocate, and returns 0 (null struct). When the timer then expires, it tries to destroy a null struct, hence the other error message.

Collapse JASS:
        set t = GetTableTimer(s,"timer")
        if t==null then
            set t = GetTimer()
        else
            set dat = GetData(t)
            if dat != 0 then
                call dat.destroy()
            endif
            call EndTimer(t)
            set t = GetTimer()
        endif
12-13-2008, 08:20 AM#3
Karawasa
Thanks.