Difference between revisions of "SizeOf/ru"
Line 115: | Line 115: | ||
Однако <syntaxhighlight lang="pascal" enclose="none">sizeOf(sizeInt)</syntaxhighlight> был вставлен только для демонстрационных целей. В ветке <syntaxhighlight lang="pascal" enclose="none">{$ifdef CPUx86_64}</syntaxhighlight> <syntaxhighlight lang="pascal" enclose="none">sizeOf(sizeInt)</syntaxhighlight> всегда равен <syntaxhighlight lang="pascal" enclose="none">8</syntaxhighlight>. | Однако <syntaxhighlight lang="pascal" enclose="none">sizeOf(sizeInt)</syntaxhighlight> был вставлен только для демонстрационных целей. В ветке <syntaxhighlight lang="pascal" enclose="none">{$ifdef CPUx86_64}</syntaxhighlight> <syntaxhighlight lang="pascal" enclose="none">sizeOf(sizeInt)</syntaxhighlight> всегда равен <syntaxhighlight lang="pascal" enclose="none">8</syntaxhighlight>. | ||
− | == | + | == Сравнительные замечания == |
− | === | + | === Динамические массивы и тому подобное === |
Since [[Dynamic array|dynamic arrays]] are realized as pointers to a block on the heap, <syntaxhighlight lang="pascal" enclose="none">sizeOf</syntaxhighlight> evaluates to the pointer's size. | Since [[Dynamic array|dynamic arrays]] are realized as pointers to a block on the heap, <syntaxhighlight lang="pascal" enclose="none">sizeOf</syntaxhighlight> evaluates to the pointer's size. | ||
In order to determine the array's size – of its data – <syntaxhighlight lang="pascal" enclose="none">sizeOf</syntaxhighlight> has to be used in conjunction with the function {{Doc|package=RTL|unit=system|identifier=length|text=<syntaxhighlight lang="pascal" enclose="none">length</syntaxhighlight>}}. | In order to determine the array's size – of its data – <syntaxhighlight lang="pascal" enclose="none">sizeOf</syntaxhighlight> has to be used in conjunction with the function {{Doc|package=RTL|unit=system|identifier=length|text=<syntaxhighlight lang="pascal" enclose="none">length</syntaxhighlight>}}. |
Revision as of 23:12, 23 April 2019
│
Deutsch (de) │
English (en) │
suomi (fi) │
русский (ru) │
Функция времени компиляции sizeOf
вычисляет размер в байтах данного имени типа данных или идентификатора переменной.
sizeOf
также может применяться в выражениях времени компиляции внутри директив компилятора.
Использование
sizeOf
особенно часто встречается в ассемблере или при ручном выделении памяти:
1program sizeOfDemo(input, output, stderr);
2
3{$typedAddress on}
4
5uses
6 heaptrc;
7
8type
9 s = record
10 c: char;
11 i: longint;
12 end;
13
14var
15 x: ^s;
16
17begin
18 returnNilIfGrowHeapFails := true;
19
20 getMem(x, sizeOf(x));
21
22 if not assigned(x) then
23 begin
24 writeLn(stderr, 'malloc for x failed');
25 halt(1);
26 end;
27
28 x^.c := 'r';
29 x^.i := -42;
30
31 freeMem(x, sizeOf(x));
32end.
Прямая обработка структурированных типов данных на ассемблере также требует знания размеров данных:
1program sizeOfDemo(input, output, stderr);
2
3type
4 integerArray = array of integer;
5
6function sum(const f: integerArray): int64;
7{$ifdef CPUx86_64}
8assembler;
9{$asmMode intel}
10asm
11 // убеждаемся, что f находится в конкретном регистре
12 mov rsi, f // rsi := f (указатель на массив)
13
14 // проверка на пустой (nil) указатель (напр. пустой массив)
15 test rsi, rsi // rsi = 0 ?
16 jz @sum_abort // если rsi = nil, то переходим к @sum_abort
17
18 // загружаем последний индекс массива [теоретически это верхний элемент массива F]
19 mov rcx, [rsi] - sizeOf(sizeInt) // rcx := (rsi - sizeOf(sizeInt))^
20
21 // загружаем первый элемент, поскольку условие цикла не дойдет до него
22 {$if sizeOf(integer) = 4}
23 mov eax, [rsi] // eax := rsi^
24 {$elseif sizeOf(integer) = 2}
25 mov ax, [rsi] // ax := rsi^
26 {$else} {$error неожиданный целочисленный размер} {$endif}
27
28 // мы сделаем, если f не содержит больше элементов
29 test rcx, rcx // rcx = 0 ?
30 jz @sum_done // если high(f) = 0, то переходим к @sum_done
31
32@sum_iterate:
33 {$if sizeOf(integer) = 4}
34 mov edx, [rsi + rcx * 4] // edx := (rsi + 4 * rcx)^
35 {$elseif sizeOf(integer) = 2}
36 mov dx, [rsi + rcx * 2] // dx := (rsi + 2 * rcx)^
37 {$else} {$error неожиданный масштабный коэффициент} {$endif}
38
39 add rax, rdx // rax := rax + rdx
40
41 jo @sum_abort // если OF, то переходим к @sum_abort
42
43 loop @sum_iterate // dec(rcx)
44 // если rcx <> 0, то переходим к @sum_iterate
45
46 jmp @sum_done // переходим к @sum_done
47
48@sum_abort:
49 // загружаем нейтральный элемент для прибавления
50 xor rax, rax // rax := 0
51
52@sum_done:
53end;
54{$else}
55unimplemented;
56begin
57 sum := 0;
58end;
59{$endif}
60
61begin
62 writeLn(sum(integerArray.create(2, 5, 11, 17, 23)));
63end.
В FPC размер integer
зависит от используемого режима компилятора.
Однако sizeOf(sizeInt)
был вставлен только для демонстрационных целей. В ветке {$ifdef CPUx86_64}
sizeOf(sizeInt)
всегда равен 8
.
Сравнительные замечания
Динамические массивы и тому подобное
Since dynamic arrays are realized as pointers to a block on the heap, sizeOf
evaluates to the pointer's size.
In order to determine the array's size – of its data – sizeOf
has to be used in conjunction with the function length
.
1program dynamicArraySizeDemo(input, output, stderr);
2
3uses
4 sysUtils;
5
6resourcestring
7 enteredN = 'You''ve entered %0:d integers';
8 totalData = 'occupying a total of %0:d Bytes.';
9
10var
11 f: array of longint;
12
13begin
14 setLength(f, 0);
15
16 while not eof() do
17 begin
18 setLength(f, length(f) + 1);
19 readLn(f[length(f)]);
20 end;
21
22 writeLn(format(enteredN, [length(f)]));
23 writeLn(format(totalData, [length(f) * sizeOf(f[0])]));
24end.
The approach is the same for ANSI strings (depending on the {$longstrings}
compiler switch state possibly denoted by string
, too).
Do not forget that dynamic arrays have management data in front of the referenced payload block.
So if you really want to know, how much memory has been reserved for one array, you would have to take the high (last index in array) and reference count fields into account, too.
classes
Classes as well are pointers.
The class TObject
provides the function instanceSize
.
It returns an object's size as it is determined by the class's type definition.
Additional memory that's allocated by constructors or any method, is not taken into account.
Note, that classes might contain dynamic arrays or ANSI strings, too.