Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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.032 c
14-1083836804
oflaund
2004-05-06 13:46
2004.05.30
Помогите решить задачу на pascal e


1-1084772509
nkoleda
2004-05-17 09:41
2004.05.30
Excel подвисает


1-1085039816
$Hic0
2004-05-20 11:56
2004.05.30
Try... except


14-1084354990
xman
2004-05-12 13:43
2004.05.30
Ассемблер


1-1084967677
TUser
2004-05-19 15:54
2004.05.30
TListItems.Add





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский