allocate will return an integer between 1 and 8192 (or what ever limit is set).
The returned integer is lets say "in use", so alloc won't return an integer which is already in use.
So at maximum alloc can provide you max with 8k unique integers.
Now there is deallocate. It's called to recylce an integer to the alloc pool again, once you don't need it anymore.
So when you deallocate one integer, then now it can be used for allocation again in future.
So the whole alloc system is marely to provide unique integers always when you need it.
This is, because structs in vjass are integers in the background.
Struct members are arrays, and alloc gives us the unique index for the array for our instances/objects to use the array.
JASS:
struct Point // Point is a integer array, Point[]
real x // is actually an array x[]
real y // is it actually an array y[]
static method create takes nothing returns thistype
local thistype this = allocate() // "this" will be an integer, uniquely used for the struct
set this.x = 1
set this.y = 2
return this
endmethod
endstruct
.. in background, if it's not vjass anymore, but pure jass, the create method looks like:
JASS:
this = 1
Point_x[this] = 1
Point_y[this] = 2
return this
So our struct instance "this" is just a unique index for the array.
The "Point_" prefix is just so the name x and y don't collide with other names x/y of other structs.
On "how" a alloc actually works in background, to provide always one unique integer is not really interesting for users and for me personally. They just want that it gives integers and recylced them if not needed anymore. But one can anaylse their code to get the tequnique.
There are simpler allocs that marely focus on the integer pool so it can be used, and complex ones, like the one linked by Nestharus, with huge overhead next to functionality. Providing more analysis and safety in case of errors.