What happens if we create more structs than we're allowed to

Status
Not open for further replies.
Level 15
Joined
Aug 7, 2013
Messages
1,337
Hi,

If for some reason we allocate more structs than can be allowed for, what happens to the newly made structs?

Suppose I filled an array of this struct below, where it has a single field marking its position in my array.

JASS:
struct myStruct
integer i
  static method create takes integer i returns thistype
  ...
  endmethod
endstruct

I now have an array of myStruct[8192] which I have filled with 8192 unique instances of myStruct, as shown below.

JASS:
myStruct array myStructs[8192]
...
local integer i = 0
loop
  exitwhen i == 8192
  set myStructs[i] = myStruct.create(i)
  set i = i + 1
endloop

Obviously if I print each member in my array and its field I should get this output.
0
1
2
...
8191

But what happens if I decide just to create another struct.
JASS:
  local myStruct a = myStruct.create(-1)

When I print out my array again, will this new struct have replaced one of the array members? So basically I'll see a -1 pop up in the middle of the print out, replacing one of the numbers.
0
1
2
...
//somewhere a has replaced a struct
-1
...
8191
 
vJASS checks for overflow. It won't create the struct, it'll just return 0.

With Alloc, it only checks for overflow in debug mode. It does not continue executing your code, it disables your entire game and gives you an error message. You will not be able to run anymore code that does error checking.

The error message for Alloc includes

library where the error occurred
method where the error occurred
instance
message

This is one of the reasons why some people use Alloc over vJASS =)

Alternatively, you can write the letter a or something in your create method and then hit save. From there, you can look at the generated vJASS code and see what happens for yourself.

JASS:
function s__a__allocate takes nothing returns integer
 local integer this=si__a_F //first node on recycle stack
    if (this!=0) then
        set si__a_F=si__a_V[this] //set stack to next node (like stack.next)
    else
        set si__a_I=si__a_I+1
        set this=si__a_I
    endif
    if (this>8190) then //protection against too many structs
        return 0
    endif

    set si__a_V[this]=-1 //set stack to -1 (stack.next = -1)
 return this
endfunction

deallocate if ur curious

JASS:
[//Generated destructor of a
function s__a_deallocate takes integer this returns nothing
    if this==null then //don't deallocate null instance
        return
    elseif (si__a_V[this]!=-1) then //double free protection
        return
    endif
    set si__a_V[this]=si__a_F //set this.next = stack
    set si__a_F=this //set stack = this
endfunction

edit
You can find Alloc and other useful resources in the "My Resources" link found in my signature. Alloc also includes special debug methods that will check how much memory you're currently using.

edit
here is the Alloc code. It's much shorter and much cleaner.

JASS:
        static method allocate takes nothing returns thistype
            local thistype this = recycler[0]
            
            debug call ThrowError(this == 0, "Alloc", "allocate", "thistype", 0, "Overflow.")
            
            set recycler[0] = recycler[this]
            debug set recycler[this] = -1
            
            return this
        endmethod
        
        method deallocate takes nothing returns nothing
            debug call ThrowError(recycler[this] != -1, "Alloc", "deallocate", "thistype", this, "Attempted To Deallocate Null Instance.")
            
            set recycler[this] = recycler[0]
            set recycler[0] = this
        endmethod
 
Status
Not open for further replies.
Top