Текущий архив: 2004.11.14;
Скачать: CL | DM;
ВнизКак в программе хранятся record ? В виде смещений, или чего то Найти похожие ветки
← →
Кто---то © (2004-10-31 02:55) [0]ещё ? Как если в рекорде присутствует string, с переменной длиной ? Существует ли функции, типа countrecotds, чтобы сосчитать все рекорды в программе, поодобно тому как подсчитываются компоненты и формы ? И вообще какие информативные функции по рекордам существуют ?
← →
GuAV © (2004-10-31 02:07) [1]
> string
ShortString знаимает 255 или меньше, как объявлео, а обычный - 4 байта.
← →
Defunct © (2004-10-31 02:10) [2]> Как в программе хранятся record ?
Хранится по принципу как есть, с выравниванием полей на границу Dword. Если выравнивание не нужно, используем packed record.
> Как если в рекорде присутствует string, с переменной длиной ?
Зависит от String"a. ShortString целиком размещается как поле в record, String хранится в виде указателя.
> Существует ли функции, типа countrecotds, чтобы сосчитать все рекорды в программе, подобно тому как подсчитываются компоненты и формы ?
Нет, такого демона нет, да и не нужна по большому счету такая функция.
> И вообще какие информативные функции по рекордам существуют ?
Record это тип.
соответственно функции характерные для всех типов.
например, SizeOf.
← →
Кто---то © (2004-10-31 02:24) [3]
> Defunct © (31.10.04 02:10) [2]
> Нет, такого демона нет, да и не нужна по большому счету
> такая функция.
А возможно ли её хотя бы написать, и если да, то как ? Где там эти смещения и выравнивания хранятся ?
← →
GuAV © (2004-10-31 02:41) [4]Кто---то © (31.10.04 2:24) [3]
Где там эти смещения и выравнивания хранятся ?
Считай что нигде. В сам код жетко прописываются по месту использования записи если она использованна.
← →
Defunct © (2004-10-31 02:42) [5]> А возможно ли её хотя бы написать, и если да, то как ?
Ну это все равно, что написать функцию подсчета всех переменных типа Integer, т.е. IMHO нереально.
> Где там эти смещения и выравнивания хранятся ?
В сегменте данных либо в стеке, в зависимости от того где объявлена переменная типа record.
Выравнивания вообще не хранятся. выравнивание по Dword это размещение поля(переменной) по адресу кратному 4.
Про смещения я кажется вообще ничего не говорил.
физически могу нарисовать картинку размещения record"a с выравниванием:Type TMyRecord = record
I : Integer;
W : Word;
B : Byte;
S : String[10];
P : Pointer;
End;
Rec : TMyRecord
Адрес памяти (rec) Поле
xxxx0000 I (4 байта)
xxxx0004 W (2 байта)
xxxx0008 B (1 байт)
xxxx000C S (10 байт)
xxxx0018 P (4 байта)
итого 28 байт.
И без выравнивания:Type TMyRecord = packed record
I : Integer;
W : Word;
B : Byte;
S : String[10];
P : Pointer;
End;
Rec : TMyRecord
Адрес памяти (rec) Поле
xxxx0000 I (4 байта)
xxxx0004 W (2 байта)
xxxx0006 B (1 байт)
xxxx0007 S (10 байт)
xxxx0011 P (4 байта)
итого 17 байт.
PS: Если я где-то ошибся подправьте.
← →
Defunct © (2004-10-31 02:48) [6]> PS: Если я где-то ошибся подправьте.
уже сам вижу ошибки:
1. не String[10], а String[9]
2. не 17 байт а 21.
← →
Кто---то © (2004-11-01 03:19) [7]
> физически могу нарисовать картинку размещения record"a с
> выравниванием:
А написать программу, которая сама бы рисовала картинку размещения своих рекордов могёте ?
← →
PVOzerski © (2004-11-01 09:28) [8]А написать класс-наследник от tComponent и использовать вместо record - не решение? Хотя, конечно, с точки зрения ресурсов ресурсов это не очень хорошо. Или динамический массив Record"ов - есть Length и индексы элементов.
← →
Sapersky (2004-11-01 10:48) [9]PS: Если я где-то ошибся подправьте.
Если брать String[9], то для незапакованной записи SizeOf = 24 (Delphi5).
См. хелп к Дельфи, memory management, records - там написано, что границей выравнивания для всех ordinal types является size of the type (1, 2, 4, or 8).
Практически это можно понимать так - дополнительные байты вставляются только тогда, когда поле записи попадает на границу двойного слова. А если не попадает, данные укладываются с обычной плотностью, так, в описанном примере W : Word; и B : Byte; влезают в одно четырёхбайтовое слово. Собственно, туда влезает даже кусочек последующего String - т.к. у ShortString выравнивание 1 (что довольно странно, вообще говоря). Но у последнего (Pointer) выравнивание таки 4 - поэтому к остатку String, занимающему 9 байт, добавляется 3 пустых байта. Если картинкой, то вот:
Адрес памяти (rec) Поле
xxxx0000 I (4 байта)
xxxx0004 W (2 байта)
xxxx0006 B (1 байт)
xxxx0007 S (10 байт)
xxxx0020 P (4 байта)
Вообще, выравнивание в Дельфи - довольно мутная тема :(, поэтому я обычно выравниваю вручную (добавляя дополнительные поля).
А написать программу, которая сама бы рисовала картинку размещения своих рекордов могёте ?
А зачем?
← →
Sapersky (2004-11-01 10:59) [10]Э-э, адреса у меня на "картинке" указаны десятичные (к HEX"ам пока не привык :))
← →
Кто---то © (2004-11-02 01:57) [11]
> PVOzerski © (01.11.04 09:28) [8]
> А написать класс-наследник от tComponent и использовать
> вместо record - не решение?
А мне интересно именно рекорды. Способность программ на Дельфи к самоисследованию.
← →
Almaz © (2004-11-02 02:18) [12]
> А мне интересно именно рекорды. Способность программ на
> Дельфи к самоисследованию.
Нет таких способностей, по крайней мере в плане record"ов точно. Record - это описание типа и не более того. Запись типа:type
TMyRec = record
A: Integer;
B: Integer;
C: String;
end;
лишь "говорит" компилятору о том, что если он , например, встретит в процедуре объявление var Rec: TMyRec - то это указание выделить в стеке 12 байт под локальную переменную, а конструкция Rec.B := 10; это указание взять адрес Rec прибавить к нему 4 и по полученному адресу записать значение 10. Все объявления, описания и имена типов "запись" существуют только на этапе компиляции в готовом коде нет никаких TMyRec - есть лишь область памяти и смещения адресов. Поэтому "функции, типа countrecotds" просто невозможны т.к. по большому счету считать - то нечего.
Удачи.
p.s. Если не секрет, а зачем Вам это ?
← →
Кто---то © (2004-11-02 05:17) [13]
> Все объявления, описания и имена типов "запись" существуют
> только на этапе компиляции в готовом коде нет никаких TMyRec
> - есть лишь область памяти и смещения адресов.
О них то и речь. Как определить эту область памяти (раз она всё таки отводится) и смещения адресов ?
← →
Digitman © (2004-11-02 08:35) [14]
> Кто---то © (02.11.04 05:17) [13]
> Как определить эту область памяти (раз она всё таки отводится)
> и смещения адресов ?
TMyRec = record
f1: TMyType1;
f2: TMyType2;
end;
..
var
MyRec: TMyRec;
..
showmessage(inttohex(integer(@MyRec), 8); //адрес области памяти, распределенный под рекорд
showmessage(inttohex((integer(@MyRec.f1) - integer(@MyRec)), 8); //смещение поля f1
showmessage(inttohex((integer(@MyRec.f2) - integer(@MyRec)), 8); //смещение поля f2
ты это имел ввиду ?
← →
Кто---то © (2004-11-03 01:33) [15]
> ты это имел ввиду ?
Это. А размеры всех полей можно ? Без упоминания их имён.
← →
GuAV © (2004-11-03 01:48) [16]Кто---то © (03.11.04 1:33) [15]
А размеры всех полей можно ?
Можно SizeOf(MyRec.f1); SizeOf(MyRec.f2);
Кто---то © (03.11.04 1:33) [15]
Без упоминания их имён.
Тоже можно
SizeOf(TMyType1); SizeOf(TMyType2);
← →
Кто---то © (2004-11-03 01:56) [17]
> GuAV © (03.11.04 01:48) [16]
> Кто---то © (03.11.04 1:33) [15]
> А размеры всех полей можно ?
> Можно SizeOf(MyRec.f1); SizeOf(MyRec.f2);
>
> Кто---то © (03.11.04 1:33) [15]
> Без упоминания их имён.
> Тоже можно
> SizeOf(TMyType1); SizeOf(TMyType2);
Сказал же, без имён. Если у тебя двести полей, то так и будешь для каждого строчку кода писать ?
Страницы: 1 вся ветка
Текущий архив: 2004.11.14;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.043 c