Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.30;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.024 c
14-1084128355
VID
2004-05-09 22:45
2004.05.30
Как узнать в какой папке лежат файлы...


14-1083869414
lak
2004-05-06 22:50
2004.05.30
вопрос html


1-1084538505
Fishka
2004-05-14 16:41
2004.05.30
ComboBox и свой Hint для каждого Item


9-1075144796
Antichrist
2004-01-26 22:19
2004.05.30
освещение объектов в <b>двухмерной</b> графике


4-1082520099
marina
2004-04-21 08:01
2004.05.30
Рисование