Форум: "Потрепаться";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
Внизpacked array Найти похожие ветки
← →
OlegGashev © (2004-05-08 18:05) [40]
program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
type c=packed record
a:integer;
c:byte;
end;
type d=record
a:integer;
c:byte;
end;
var
a:array[0..9]of c;
b:packed array[0..9] of c;
e:array[0..9]of d;
f:packed array[0..9] of d;
begin
writeln("sizeof(a)=",sizeof(a));
writeln("sizeof(b)=",sizeof(b));
writeln("sizeof(e)=",sizeof(e));
writeln("sizeof(f)=",sizeof(f));
writeln("sizeof(c)=",sizeof(c));
writeln("sizeof(d)=",sizeof(d));
readln;
end.
Выводы?
← →
Romkin © (2004-05-08 18:07) [41]Тимохов © (08.05.04 17:57) [32] Если не ошибаюсь, есть дока, что array of char всегда упакован, для совместимости со строкой... Где-то мелькало. А вот остальные типы - фирма не гарантирует ;) В D какой-то версии они могут стать и не упакованными...
← →
SPeller © (2004-05-08 18:07) [42]
> Anatoly Podgoretsky © (08.05.04 18:05) [38]
TMy2 = record
f1, f2: Byte;
i1: Integer;
end;
8 байт занимает.
← →
Тимохов © (2004-05-08 18:09) [43]темный лес это все...
для себя я сделал вывод:
важно, чтобы было все упакованно - пиши packed и не задумывайся о большем - нужно это, не нужно - пиши и все тут :)).
не важно - не пиши packed.
я домой...
← →
Romkin © (2004-05-08 18:10) [44]Млин, что вы мучаетесь? Раздел Memory Management меняется от версии к версии Delphi очень заметно, и иногда неожиданно :)))
← →
SPeller © (2004-05-08 18:11) [45]
> OlegGashev © (08.05.04 18:05) [40]
sizeof(a)=50
sizeof(b)=50
sizeof(e)=80
sizeof(f)=80
sizeof(c)=5
sizeof(d)=8
Где вывод?
← →
OlegGashev © (2004-05-08 18:12) [46]SPeller © (08.05.04 18:11) [45]
Packed работает только с record. Для массива он бесполезен.
← →
Anatoly Podgoretsky © (2004-05-08 18:13) [47]Тимохов © (08.05.04 18:09) [43]
Нет писать надо вдумчиво, иначе может быть не то, на что расчитываешь.
← →
SPeller © (2004-05-08 18:14) [48]
> OlegGashev © (08.05.04 18:12) [46]
Ну дык, мы и пытаемся найти то место, где packed array отличается от array. Я пока прихожу к выводу что в сегодняшних версиях Дельфи разницы нет.
← →
Verg © (2004-05-08 18:14) [49]
> Anatoly Podgoretsky © (08.05.04 18:13) [47]
> Тимохов © (08.05.04 18:09) [43]
> Нет писать надо вдумчиво, иначе может быть не то, на что
> расчитываешь.
Да, точно - надо делать, чтобы лучше.
← →
y-soft © (2004-05-08 18:14) [50]Действительно, в D5 массивы всегда упакованные
И когда успели :)
← →
OlegGashev © (2004-05-08 18:15) [51]SPeller © (08.05.04 18:14) [48]
Разницы я пока тоже не вижу.
← →
Anatoly Podgoretsky © (2004-05-08 18:16) [52]Verg © (08.05.04 18:14) [49]
Нет Мерзляев сказал
Не надо как лучше, надо как правильно
← →
Verg © (2004-05-08 18:20) [53]
> Anatoly Podgoretsky © (08.05.04 18:16) [52]
А фигали нам, потому что как.
← →
OlegGashev © (2004-05-08 18:22) [54]SPeller © (08.05.04 18:14) [48]
Единственную разницу я нашел только тогда, когда array находится в record:program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
type c=packed record
a:array[1..2]of integer;
c:byte;
end;
type d=record
a:array[1..2]of integer;
c:byte;
end;
var
a:array[0..9]of c;
b:packed array[0..9] of c;
e:array[0..9]of d;
f:packed array[0..9] of d;
begin
writeln("sizeof(a)=",sizeof(a));
writeln("sizeof(b)=",sizeof(b));
writeln("sizeof(e)=",sizeof(e));
writeln("sizeof(f)=",sizeof(f));
writeln("sizeof(c)=",sizeof(c));
writeln("sizeof(d)=",sizeof(d));
readln;
end.
иprogram Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
type c=packed record
a:array[1..2]of integer;
c:byte;
end;
type d=record
a:packed array[1..2]of integer;
c:byte;
end;
var
a:array[0..9]of c;
b:packed array[0..9] of c;
e:array[0..9]of d;
f:packed array[0..9] of d;
begin
writeln("sizeof(a)=",sizeof(a));
writeln("sizeof(b)=",sizeof(b));
writeln("sizeof(e)=",sizeof(e));
writeln("sizeof(f)=",sizeof(f));
writeln("sizeof(c)=",sizeof(c));
writeln("sizeof(d)=",sizeof(d));
readln;
end.
Посмотри на d=record.
То есть packed имеет смысл только тогда, когда сам массив является полем какой-то записи.
← →
Anatoly Podgoretsky © (2004-05-08 18:27) [55]Дельфи 5
type
rec1 = record
b1: Byte; //0
b2: Byte; //1
i: Integer; //4
end;
rec2 = record
b1: Byte; //0
i: Integer; //4
b2: Byte; //8
end;
rec3 = record
i: Integer; //0
b1: Byte; //5
b2: Byte; //6
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a: array [1..10] of Rec1;
b: array [1..10] of Rec1;
c: array [1..10] of Rec1;
begin
Label1.Caption := IntToStr(SizeOf(Rec1));
Label2.Caption := IntToStr(SizeOf(Rec2));
Label3.Caption := IntToStr(SizeOf(Rec3));
Label4.Caption := IntToStr(SizeOf(a));
Label5.Caption := IntToStr(SizeOf(b));
Label6.Caption := IntToStr(SizeOf(c));
end;
8, 12, 8, 80, 80, 80
← →
Anatoly Podgoretsky © (2004-05-08 18:29) [56]Ошибся
var
a: array [1..10] of Rec1;
b: array [1..10] of Rec2;
c: array [1..10] of Rec3;
8, 12, 8, 80, 120, 80
← →
SPeller © (2004-05-08 18:30) [57]
> OlegGashev © (08.05.04 18:22) [54]
Выходит что если в полях записи есть packed array, то и запись становится упакованной?
> Anatoly Podgoretsky © (08.05.04 18:27) [55]
a: array [1..10] of Rec1;
b: array [1..10] of Rec1;
c: array [1..10] of Rec1;
Может имелось ввиду
a: array [1..10] of Rec1;
b: array [1..10] of Rec2;
c: array [1..10] of Rec3;
?
← →
SPeller © (2004-05-08 18:31) [58]
> Anatoly Podgoretsky © (08.05.04 18:29) [56]
Это и так понятно, причем тут packed?
← →
OlegGashev © (2004-05-08 18:33) [59]SPeller © (08.05.04 18:30) [57]
Вроде получается такой вывод.
← →
SPeller © (2004-05-08 18:39) [60]type d=record
a:packed array[1..1]of integer;
c:word;
w:packed array [1..1] of integer;
10
type d=record
a:packed array[1..1]of integer;
c:word;
w:array [1..1] of integer;
12
Где истина?
← →
OlegGashev © (2004-05-08 18:44) [61]SPeller © (08.05.04 18:39) [60]
В первом случае у тебя packed для обоих массивов, во втором токо для одного. Т.е. packed работает только для определенного массива в самом record. Там где у тебя стоит packed, размер записи меньше.
← →
Anatoly Podgoretsky © (2004-05-08 18:45) [62]Во втором случае W вывровнено по границе 4 байт, в первом сказано не надо этого делать. Надеюсь выравнивание указано анонимное на усмотрение компилятора. Поскольку в Д6 и выше можно указать параметры выравнивая, жалко только что отсутствует выравнивание по границе 16 байт.
← →
SPeller © (2004-05-08 18:49) [63]Ага, выходит что packed array внутри записи говорит выравнивать денное поле внутри записи или нет.
← →
SPeller © (2004-05-08 18:56) [64]Хм, вот ведь какая штука выходит. Я тут поэкспериментировал и получил такой результат. Есди мы имеем такую запись:
TMy = record
b1: Byte;
i1: array [1..1] of Integer;
w1: Word;
i2: array [1..1] of Integer;
w2: Word;
i3: Integer;
end;
То запись занимает 24 байта и в памяти все поля выравнены по 4-байтной границе. Теперь если поменять объявление на такое:
TMy = record
b1: Byte;
i1: array [1..1] of Integer;
w1: Word;
i2: packed array [1..1] of Integer;
w2: Word;
i3: Integer;
end;
то запись теперь станет занимать 20 байт, а в памяти это выглядит ещё интереснее :) Поля b1 и i1 занимают вместе 8 байт, то есть выравняны по 4-байтной границе, но дальше интереснее - все последующие поля (w1, i2, w2, i3) - НЕ выравняны, тоесть идут друг за другом! Вот такие чудеса :-)) Тестил на Дельфи 6.2
← →
SPeller © (2004-05-08 19:02) [65]Дальше определил такую странность: невыравняными становятся только предыдущее и последующее поле в записи. Остальные следуют выравняными.
← →
y-soft © (2004-05-08 19:07) [66]Что-то заинтересовался я странностями с packed array, попробовал найти разъяснения в инете, но даже у Борланда (http://info.borland.com/techpubs/delphi/delphi5/oplg/datatype.html)все то же самое:
By default, the values in a structured type are aligned on word or double-word boundaries for faster access. When you declare a structured type, you can include the reserved word packed to implement compressed data storage. For example,
type TNumbers = packed array[1..100] of Real;
Т.е. в качестве примера использования приводится опять-таки именно packed array! А факты говорят совсем о другом...
← →
Anatoly Podgoretsky © (2004-05-08 19:08) [67]SPeller © (08.05.04 18:49) [63]
Нет Packed array ни как не может влиять на запись. Для этого надо иметь упакованную записи или в случае если сама запись также включает структурные элементы, то для них тоже надо отдельно указывать выравнивание, это демонстрируется в твоем примере [60]. Packed array может относиться только к простым массивам и то в зависимости от версии компилятора, а их уже очень много - 15.
← →
SPeller © (2004-05-08 19:10) [68]Точно, подтвердилось. Если в записи используется упакованный массив, то невыравнянными в записи становятся сам массив, предыдущее и следующие поля. Вот код:
type
TMy = record
b1: Byte;
i1: array [1..1] of Integer;
b2: Byte;
i2: packed array [1..1] of Integer;
b3: Byte;
i3: Integer;
b4: Byte;
end;
var
V: TMy;
hf: THandle;
tm: Cardinal;
begin
V.b1 := $CC;
V.i1[1] := $FFFFFFFF;
V.b2 := $AA;
V.i2[1] := $FFFFFFFF;
V.b3 := $AA;
V.i3 := $BBBBBBBB;
V.b4 := $CC;
hf := CreateFile( "C:\1.bin", GENERIC_WRITE, 0, nil, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0 );
WriteFile( hf, V, SizeOf( V ), tm, nil );
CloseHandle( hf );
end;
Посмотрите что в файле получается. У меня так:
Размер 24
CC 00 00 00 FF FF FF FF AA FF FF FF FF AA FD 7F
BB BB BB BB CC E0 E6 77
Тут видно что кроме всего прочего спонтанно появляется мусор в незаполненном пространстве записи (FD, 7F, E0, E6 и 77).
← →
SPeller © (2004-05-08 19:13) [69]
> Anatoly Podgoretsky © (08.05.04 19:08) [67]
Опыт показывает что всё-таки влияет. Вот пример, если убрать у массива packed:
Размер 28
CC -- -- -- FF FF FF FF AA -- -- -- FF FF FF FF
AA -- -- -- BB BB BB BB CC -- -- --
Тут прочерками я заменил мусор, чтобы нагляднее было.
← →
SPeller © (2004-05-08 19:15) [70]Без мусора упакованная запись выгляди так:
CC 00 00 00 FF FF FF FF AA FF FF FF FF AA -- --
BB BB BB BB CC -- -- --
Вот вам и выводы, уважаемые господа.
← →
SPeller © (2004-05-08 19:15) [71]Сорри, не совсем точно :)
CC -- -- -- FF FF FF FF AA FF FF FF FF AA -- --
BB BB BB BB CC -- -- --
← →
SPeller © (2004-05-08 19:17) [72]Я понимаю что упакованный массив не должен влиять на внутреннее представление записи, но влияет. Д6.2. Только остаётся вопрос: баг это или фича?
← →
Anatoly Podgoretsky © (2004-05-08 19:18) [73]SPeller © (08.05.04 19:15) [70]
Сообственно вывод простой, использовать только тогда когда действительно нужно выравнивание, при том ко всем структурам, а не только к массивам.
← →
SPeller © (2004-05-08 19:21) [74]Угу, согласен :)
← →
OlegGashev © (2004-05-08 19:21) [75]Я тебе уже написал в прошлых постингах, что упакованный массив влияет на размер записи.
← →
SPeller © (2004-05-08 19:24) [76]
> OlegGashev © (08.05.04 19:21) [75]
Зато как хитро он влияет :-))
← →
Verg © (2004-05-08 19:50) [77]
> SPeller © (08.05.04 19:13) [69]
Если вы в записи замените packed array на packed record, то эффект будет то же самый.
Т.о. array это или не array значения не имеет.
← →
Verg © (2004-05-08 19:59) [78]Появление packed поля в структуре автоматически делает всю структуру packed. Префикс packed у массива никак не влияет на устройство самого массива.
← →
SPeller © (2004-05-09 05:01) [79]
> Появление packed поля в структуре автоматически делает всю
> структуру packed.
Нифига. :) Я ж тут наглядно показал что не вся структура упаковывается, а только часть полей.
← →
SPeller © (2004-05-09 05:04) [80]И действительно, packed record приводит к такому же результату.
Страницы: 1 2 3 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
Память: 0.62 MB
Время: 0.033 c