Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Динамические массивы [D6]


Alex2 ©   (2005-12-22 08:21:00) 

Уважаемые мастера, у меня возник вопрос как же правильно работать с динамическими массивами.
Во многих примерах рекомендуется работать с ним через указатель:

TBoolArray = array[1..MaxBooleans] of boolean;
PBoolArray = ^TBoolArray;
B : PBoolArray;
...
GetMem(B, N*sizeof(boolean));
FreeMem(B, N*sizeof(boolean));

Но ведь когда работаешь через стандартный механизм:

TBoolArray = array of boolean;
B : TBoolArray;
...
SetLength(B, N);
B := nil;

массив B тоже представляет из себя указатель.
В чем отличие?


evvcom   (2005-12-23 08:38:00) [1]


> а можно узнать, зачем он так делает?
> ну, в двух словах?

Как он (компилятор) делает, зависит от галок, установленных/сброшенных в его настройках (оптимизация, проверка ошибок на выход из диапазона допустимых индексов, ошибки ввода/вывода и пр.) Но есть и не зависимые от настроек действия такие как инициализация/финализация массивов, записей, стрингов и пр. Этого требуют особенности поведения типов. Ведь ты ж была бы недовольна, если бы приходилось самой в конце каждой процедуры/функции/метода писать код явного освобождения подобных структур. А так поставил end; и голова пусть у компилятора болит, как он будет освобождать весь этот теперь уже мусор.

> а вообще мне кажется что Delphi это ОНИ

А все зависит от того, что под этим подразумевается: компилятор - ОН, среда - ОНА, Дельфы - ОНИ. :)


з. танька   (2005-12-22 18:25:00) [2]

а можно узнать, зачем он так делает?
ну, в двух словах?

а вообще мне кажется что Delphi это ОНИ.. (т.е. Дельфы по названию города)


evvcom   (2005-12-22 16:31:00) [3]


> А где бы узнать что конкретно компилятор дельфи при этом
> делает?

View - Debug Windows - CPU


Alex2   (2005-12-22 16:11:00) [4]


> За счет того что Делфи-компилятор  при большинстве "лобовых"
> программных обращений к дин.массиву вставляет неявный маш.
> код. который кроме собственно работы с данными массива оперирует
> еще и служебной инф-цией в той самой упр.структуре

А где бы узнать что конкретно компилятор дельфи при этом делает?


Digitman   (2005-12-22 15:58:00) [5]


> Alex2   (22.12.05 15:49) [9]


За счет того что Делфи-компилятор  при большинстве "лобовых" программных обращений к дин.массиву вставляет неявный маш.код. который кроме собственно работы с данными массива оперирует еще и служебной инф-цией в той самой упр.структуре


Alex2   (2005-12-22 15:49:00) [6]


> Недостаток - несколько меньшая скорость доступа к элементу
> (особенно у многомерных массивов).

А за счет чего уменьшается скорость, ведь фатически и там и там указатели?


evvcom   (2005-12-22 12:16:00) [7]

Точнее не у дин.массивов, а типов описывающих дин.массивы. Тогда уж стоило сказать, что TypeInfo содержится также и у многих других сложных типов, таких как record, string... А у самих переменных нет никаких ссылок на их тип.


Sapersky   (2005-12-22 11:28:00) [8]

Ещё у дин. массивов (array of <...>) есть своего рода RTTI, точнее, TypeInfo. Содержит тип, размер элемента, наличие финализируемых полей (LongString и пр.) в элементе. Весьма полезно для написания универсальных функций.
Пример есть в JCL - официально для Delphi7, фактически TypeInfo у массивов присутствует по крайней мере с D5.
Ещё достоинство, вытекающее, надо полагать, из первого - содержимое дин. массива можно посмотреть при отладке.
Недостаток - несколько меньшая скорость доступа к элементу (особенно у многомерных массивов).


evvcom   (2005-12-22 09:19:00) [9]


> сделай
> p:=PInt(a);

2 TUser: А лучше через CPU Window посмотри. Более наглядно.


MBo   (2005-12-22 08:57:00) [10]

>TUser
у тебя после
p:=@a;
p  - указатель на указатель
сделай
p:=PInt(a);


procedure TForm6.Button1Click(Sender: TObject);
var
 A:array of Integer;
begin
 SetLength(A,3);
 A[0]:=7;
 Caption:=Format('%p  %p   %d  %d',[A, @A[0], A[0], PInteger(A)^]);
end;


TUser   (2005-12-22 08:49:00) [11]


> Для одномерного массива переменная указывает все же на первый
> элемент, а управляющая структура располагается по отрицательному
> смещению от него,

???
program Ar;
{$apptype console}
uses SysUtils;

type
PInt = ^integer;

var a: array of integer;
   p: pint;
begin
 SetLength (a, 3);
 a[0]:=10;
 writeln (inttostr(a[0]));
 p:=@a;
 writeln (inttostr(p^));
 p:=@a[0];
 writeln (inttostr(p^));
end.

Delphi 7.


MBo   (2005-12-22 08:30:00) [12]

>адрес управляющей структуры этого массива, а не адрес его первого элемента

Для одномерного массива переменная указывает все же на первый элемент, а управляющая структура располагается по отрицательному смещению от него, хотя лучше в явном виде этим не пользоваться


MBo   (2005-12-22 08:27:00) [13]

Первый способ использовался в основном до появления в Delphi4 динамических массивов, реализованных подобно длинным строкам. При этом выделение-освобождение памяти производится вручную, и нет механизма подсчета ссылок.


Digitman   (2005-12-22 08:26:00) [14]


> В чем отличие?


В случае стат.массива переменная B: PBoolArray содержит адрес первого элемента этого массива

В случае дин.массива переменная B: TBoolArray содержит адрес управляющей структурыэтого массива, а не адрес его первого элемента


Наверх

Титульная страница Поиск, карта сайта Написать письмо