Форум: "Потрепаться";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
Внизpacked array Найти похожие ветки
← →
Тимохов © (2004-05-08 16:45) [0]Может ли кто-нибудь привести пример НЕупакованного массива, который бы был действительно НЕупакованный, т.е. length(array)*sizeof(element) <> sizeof(array)?
← →
VMcL © (2004-05-08 16:48) [1]>>Тимохов © (08.05.04 16:45)
AFAIK, в Delphi директива packed не имеет смысла для массивов, только для записей (records).
← →
Тимохов © (2004-05-08 16:50) [2]
> AFAIK
Да, да - я LMD, я не знаю что такое AFAIK :(((
> в Delphi директива packed не имеет смысла для массивов,
> только для записей (records).
Я в общем то тоже так думаю.
Откуда такая инфа?
← →
Vlad © (2004-05-08 17:05) [3]
> Тимохов © (08.05.04 16:50) [2]
Меня тоже интересует этот вопрос, но у меня есть одно предположение (хотя могу быть и неправ)
Если мы создаем массив array[0..X] of SomeType
то изначально память не выделяется под каждый элемент массива, а выделяется непосредственно при присвоении значения элементу, т.е. динамически. Значит изначально массив - сам по себе является упакованной структурой, потому, думаю и нет смысла объявлять его как packed
Хотя это мое предположение, возможно я и неправ.
← →
Gero © (2004-05-08 17:07) [4]
> я не знаю что такое AFAIK
AFAIK - As Far As I Know
← →
VMcL © (2004-05-08 17:08) [5]>>Тимохов © (08.05.04 16:50) [2]
>Да, да - я LMD, я не знаю что такое AFAIK
Совсем ты и не LMD :))
AFAIK = as far as I know (насколько мне известно)
( http://maxarea.narod.ru/text/rtfm.htm )
>Откуда такая инфа?
Сейчас Delphi под рукой нет, но в справке по слову packed посмотри, вроде, написано.
← →
Тимохов © (2004-05-08 17:11) [6]
> но в справке по слову packed посмотри, вроде, написано.
Нет там ничего. НЕ сказано, что массив есть исключение.
> Если мы создаем массив array[0..X] of SomeType
> то изначально память не выделяется под каждый элемент массива,
> а выделяется непосредственно при присвоении значения элемент
Имхо ты не прав - сразу же и выделяется.
← →
KilkennyCat © (2004-05-08 17:15) [7]
> Vlad © (08.05.04 17:05) [3]
когда-то двавненько я работал с ооочень громадными статичискими массивами. Сообщение о нехватке памяти получал мгновенно, при объявлении.
← →
Vlad © (2004-05-08 17:16) [8]
> Имхо ты не прав - сразу же и выделяется.
Возмем класс TList, в нем изначально создается массив
array[0..MaxListSize - 1] of Pointer
т.е. свыше 100 млн элементов. Умножь каждый на 4 байта.
Получается что создание объекта типа TList сразу отбирает свыше 4 млн байт памяти ?
Я не проверял конечно, но полагаю что это не так.
← →
Vlad © (2004-05-08 17:18) [9]пардон, не 4 млн, а 400 млн.
← →
Тимохов © (2004-05-08 17:20) [10]
> Vlad © (08.05.04 17:16) [8]
не путайте - там не массив создается, а указатель на массив.
← →
SPeller © (2004-05-08 17:23) [11]
> Если мы создаем массив array[0..X] of SomeType
... то так как классовая переменная - это всего-лишь типизированный указатель, то на каждый элемент массива выделится по 4 байта.
← →
VMcL © (2004-05-08 17:24) [12]>>Vlad © (08.05.04 17:16) [8]
Юрия Зотова на тебя нету :)
См. [10]
← →
OlegGashev © (2004-05-08 17:25) [13]Instances of a structured type hold more than one value. Structured types include sets, arrays, records, and files as well as class, class-reference, and interface types. Except for sets, which hold ordinal values only, structured types can contain other structured types; a type can have unlimited levels of structuring.
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;
Using packed slows data access and, in the case of a character array, affects type compatibility.
← →
Тимохов © (2004-05-08 17:28) [14]
> OlegGashev © (08.05.04 17:25) [13]
это из мануала дельфового.
Ну и что?
Соглавно этой доке
arrayp[0..9] of byte дожен занимать 20 майте (выравнивание по словам) или 40 байт (выравнивание по двойным словам). А он занимает ровно 10 байт.
Как вы это объясните?
Не может?
Вот и я не могу...
Для всех - у меня явно {$align on} и тоже самое в настройках проекта (для надеги :)))
← →
SPeller © (2004-05-08 17:31) [15]Лично я тоже не могу понять смысла packed array, поскольку я ниразу не сталкивался со случаем когда массив из N элементов по K байт занимал бы больше N*K байт памяти.
← →
Тимохов © (2004-05-08 17:32) [16]
> SPeller © (08.05.04 17:31) [15]
вот и я о том же.
Понятно, что если в доке сказано, что массивы тоже могут быть unpacked, то писать слово packed все-таки нужно (когда нужно я пишу). Но интересно было бы узнать хоть бы об одном примере не упакованного массива...
← →
SPeller © (2004-05-08 17:35) [17]Быть может мастера прояснят ситуацию, может кто-то всё-таки видел неупакованные массивы?
← →
Тимохов © (2004-05-08 17:36) [18]
> SPeller © (08.05.04 17:35) [17]
> Быть может мастера прояснят ситуацию, может кто-то всё-таки
> видел неупакованные массивы?
вот и я о том же :)))
Прояснил бы кто про упакованность.
← →
y-soft © (2004-05-08 17:40) [19]>Vlad © (08.05.04 17:18) [9]
Память в TList выделяется порциями, а не вся сразу на максимальную емкость (если, конечно, не заставить его это сделать принудительно)
unit Classes;
...
const
{ Maximum TList size }
MaxListSize = Maxint div 16;
...
function TList.Add(Item: Pointer): Integer;
begin
Result := FCount;
if Result = FCapacity then
Grow;
FList^[Result] := Item;
Inc(FCount);
if Item <> nil then
Notify(Item, lnAdded);
end;
...
procedure TList.Grow;
var
Delta: Integer;
begin
if FCapacity > 64 then
Delta := FCapacity div 4
else
if FCapacity > 8 then
Delta := 16
else
Delta := 4;
SetCapacity(FCapacity + Delta);
end;
...
procedure TList.SetCapacity(NewCapacity: Integer);
begin
if (NewCapacity < FCount) or (NewCapacity > MaxListSize) then
Error(@SListCapacityError, NewCapacity);
if NewCapacity <> FCapacity then
begin
ReallocMem(FList, NewCapacity * SizeOf(Pointer));
FCapacity := NewCapacity;
end;
end;
Далее - директиваpacked
означает всего лишь, что элементы структуры не выравниваются по границе слова/двойного слова
Т.е если массив состоит из элементов, размер которых некратен 2, то в неупакованном виде он действительно займет больше места
← →
Тимохов © (2004-05-08 17:42) [20]
> Т.е если массив состоит из элементов, размер которых некратен
> 2, то в неупакованном виде он действительно займет больше
> места
Эх блин, теоретики :)))
Пример с array [0..9] of byte - опровергает ваши слова...
← →
SPeller © (2004-05-08 17:43) [21]TList, на сколько я понимаю, работает с массивом указателей, а они по 4 байта. При чём тут упакованность?
← →
Vlad © (2004-05-08 17:43) [22]Ну хорошо, тогда как объяснить следующее:
Я объявляю глобальную переменную: MyArr: array[0..100000000] of Integer;
Программа занимает примерно 2 Мб памяти.
По кнопке 1 заполняю примерно четверть массива значениями
Программа стала занимать примерно 25 Мб памяти
По кнопке 2 заполняю весь массив значениями
Программа стала занимать примерно 96 Мб памяти
Получается что память все-таки выделяется непосредственно при присвоении значения элементу ?
← →
y-soft © (2004-05-08 17:44) [23]>Тимохов © (08.05.04 17:42) [20]
Это Вы о чем?
Для байта, да. А возьмите массив элементов, размером, например 3 байта?
← →
SPeller © (2004-05-08 17:48) [24]
> Для байта, да. А возьмите массив элементов, размером, например
> 3 байта?
procedure TForm1.Button2Click(Sender: PObj);
type
TMy = packed record
f1, f2, f3: Byte;
end;
var
V: array[0..99] of TMy;
begin
ShowMessage( IntЕщStr( SizeOf( V ) ) );
end;
Посмотрите, какое число выскочит?
← →
Тимохов © (2004-05-08 17:48) [25]
> y-soft © (08.05.04 17:44) [23]
будет ровно 30 байт.
пример:
t = packed record b,b1,b2: byte;
var
a: array [0..9] of t;
← →
SPeller © (2004-05-08 17:49) [26]
> IntЕщStr
Это IntToStr :)
← →
Anatoly Podgoretsky © (2004-05-08 17:49) [27]Попробуй массив записей, информация об выравнивании скудная.
Для динамических массиво вроде директива не действует.
← →
SPeller © (2004-05-08 17:49) [28]У дураков мысли сходяться :-))))))
← →
Тимохов © (2004-05-08 17:52) [29]
> Anatoly Podgoretsky © (08.05.04 17:49) [27]
> Для динамических массиво вроде директива не действует.
это понятно - судя по выделению памяти под дин. массив - там просто умножение размера элемента на кол-во элементов.
Массив записей попробован.
Сами записи если у них не стоит слово packed не упакованные, но элементы расположены невыровнено - независимо от размера записи - 1, 2, 3 и т.д. - элементы идут подряд...
← →
Verg © (2004-05-08 17:55) [30]
>
> Vlad © (08.05.04 17:43) [22]
> Ну хорошо, тогда как объяснить следующее:
> Я объявляю глобальную переменную: MyArr: array[0..100000000]
> of Integer;
> Программа занимает примерно 2 Мб памяти.
В таск-менеджере включи колоку "Виртуальная память" и сравни.
все массивы и так packed
packed array - масло масленное
← →
SPeller © (2004-05-08 17:57) [31]Такой код
procedure TForm1.Button2Click(Sender: PObj);
type
TMy = packed record
f1, f2, f3: Byte;
end;
var
V: array of TMy;
hf: THandle;
tm: Cardinal;
begin
SetLength(V, 10);
V[0].f1 := $FF;
V[0].f2 := $FF;
V[0].f3 := $FF;
V[1].f1 := $FF;
V[1].f2 := $FF;
V[1].f3 := $FF;
hf := CreateFile( "C:\1.bin", GENERIC_WRITE, 0, nil, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0 );
WriteFile( hf, V[0], 8, tm, nil );
CloseHandle( hf );
end;
Показывает что всё-равно друг за другом.
← →
Тимохов © (2004-05-08 17:57) [32]
> все массивы и так packed
Ну вот и скажите, где это написано...
:))))))
Перефразирую свой вопрос: знает ли кто-нибудь официальную доку борланда, где было бы сказно, что все массивы packed?
← →
Romkin © (2004-05-08 17:59) [33]Vlad © (08.05.04 17:43) [22] Так. Не путайтесь. Возбмите Рихтера, и почитайте про страничную организацию памяти в Windows :) Память выделяется постранично, причем в обычном режиме ФИЗИЧЕСКИ станица выделяется, когда к ней обращаются...
Тимохов © (08.05.04 17:42) [20] Что-то в хелпе по ALIGN я ни слова про массивы не увидел :) Если память не изменяет, packed array осталось для совместимости с TP... Но Болрланд, опять же, не гарантирует. Да, в D6 выделяется по размеру элемента, но если память не изменяет, не всегда так было. Надо бы D1 откопать ;)
← →
Anatoly Podgoretsky © (2004-05-08 18:00) [34]Тимохов © (08.05.04 17:42) [20]
Нет не опровергает, правило выравнивания действует для следующего элемента, если бы за байтом следовал интегер, то можно бы было так говорить.
Тимохов © (08.05.04 17:52) [29]
Так пробовали ли ты создать массив неупакованных записей в неупаковонном массиве, например
packed record
b: byte
i: Integer
end;
← →
Verg © (2004-05-08 18:01) [35]
> Тимохов © (08.05.04 17:57) [32]
Ах вон что. Тебе справку с печатью нужно...
Я думаю, что это еще вообще не от Борланда началось. Помнится это еще со времен Pascal под RT11 повелось...
← →
Vlad © (2004-05-08 18:01) [36]
> Verg © (08.05.04 17:55) [30]
> Romkin © (08.05.04 17:59) [33]
Точно.
Все, иду читать Рихтера :-)
← →
SPeller © (2004-05-08 18:03) [37]
> packed record
> b: byte
> i: Integer
> end;
8 байт будет занимать, массив уже и выравнивать не надо.
← →
Anatoly Podgoretsky © (2004-05-08 18:05) [38]В дополнение, сейчас не могу найти статью в справке, где приводилось данное описание выравнивания.
rec1
b1: Byte; //0
b1: Byte; //1
i: Integer; //4
end;
rec2
b1: Byte; //0
i: Integer; //4
b1: Byte; //8
end;
rec3
i: Integer; //0
b1: Byte; //5
b1: Byte; //6
end;
SizeOf(Rec1)
SizeOf(Rec2)
SizeOf(Rec3)
Посмотри что будет, я не смотрел, опираюсь только на статьи и обсуждения.
← →
Verg © (2004-05-08 18:05) [39]Когда-то, когда деревъя были маленькими, такие приемчики
type
mytype = 0..3;
var
F : packed array[0..100] of mytype;
позволяло экононмит столь дефицитную тода память, сильно ухудшая при этом производительность.
← →
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.
Выводы?
Страницы: 1 2 3 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.035 c