JASS Help

Массивы

Для объявления массива используется ключевое слово array. Инициализировать массив, как и указать его размер при объявлении нельзя.

Индексация значений начинается с нуля.

globals integer array a endglobals function main takes nothing returns nothing local integer array b set a[0] = 1 set b[0] = a[0] + 2 endfunction

Для типа code массивы не поддерживаются.

Выделение памяти

Изначально любой массив имеет размер ноль. При записи значения выделяется память на количество элементов, равное значению ближайшей сверху степени двойки. Так продолжается, пока размер не достигнет максимального, указанного в переменной JASS_MAX_ARRAY_SIZE из common.j.

function main takes nothing returns nothing local integer array a // размер равен нулю set a[0] = 1 // ближайшая степень к 0 это 2^0=1, размер равен 1 set a[1] = 1 // ближайшая степень к 1 это 2^1=2, размер равен 2 set a[2] = 1 // ближайшая степень к 2 это 2^2=4, размер равен 4 set a[3] = 1 // ближайшая степень к 3 это 2^2=4, размер равен 4 set a[4] = 1 // ближайшая степень к 4 это 2^3=8, размер равен 8 set a[5] = 1 // ближайшая степень к 5 это 2^3=8, размер равен 8 set a[6] = 1 // ближайшая степень к 6 это 2^3=8, размер равен 8 //... endfunction

Ниже приведена таблица степеней двойки и максимальный размер массива для разных версий игры.

Число

Степень

Значение

Максимальный размер

2

0

1

2

1

2

2

2

4

2

3

8

2

4

16

2

5

32

2

6

64

2

7

128

2

8

256

2

9

512

2

10

1 024

2

11

2 048

2

12

4 096

2

13

8 192

Ванила

2

14

16 384

2

15

32 768

Reforged

2

16

65 536

2

17

131 072

2

18

262 144

UjAPI

Маленькая хитрость

Массив должен располагаться в памяти непрерывно, такова особенность архитектуры. Поэтому при смене размера будет найден участок памяти в который поместится новый массив и все значения будут скопированы туда. Как вы понимаете, эта операция не бесплатна и чтоб избежать лишних операций с памятью, можно прикинуть максимальное количество элементов массива и сразу выделить необходимую память:

globals integer array a endglobals function main takes nothing returns nothing set a[500] = 0 // Допустим мы прикинули, что количество элементов будет около 300 endfunction

Память выделяется в момент присваивания значения по индексу, так что само значение неважно:

globals integer array i string array s unit array u rect array r endglobals function main takes nothing returns nothing set i[500] = 0 set s[500] = "" set u[500] = null set r[500] = null endfunction

Утечка

Глобальные массивы

Ведут себя так же как и глобальные переменные и в первом приближении можно вообще относиться к ним как к переменным с хитрым синтаксисом.

Локальные массивы

Локальные массивы с типом не наследующим handle абсолютно безопасны и их использование дело вкуса.

А вот о локальных массивах с типом наследующим handle лучше забыть. При изменении размера произойдёт утечка четырёх байт на каждое значение отличное от null. Поэтому таким массивам обязательно выделять память, гарантировано покрывающим все элементы. А так же при выходе их функции в таком массиве не должно быть значений отличных от null.

Last modified: 22 October 2024