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

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

Динамические массивы vs Статические массивы [D7, WinXP]


Страницы:   1 2 3

SH@RK ©   (2007-01-31 12:47:00) 

Существуют алгоритмы, память для работы которых выделяется во время их работы. Т.е. заранее неизвестен размер массива, с которым работает алгоритм.

Пример:
type
 TNode = packed record
   Child: packed array [0..31] of Word;
   Parent: Word;
   Final: LongBool;                      
 end;                                  
 PArrNode = packed array of TNode;
var
 Node: PArrNode;   // динамич. массив


1)
В ходе выполнения алгоритма выделяю память кусками (по мере неоходимости):
Len := Length(Node);
SetLength(Node, Len + 100);


Я полагаю, что при этом элементы массива Node2^ располагаются в виртуальной памяти последовательно. Поэтому я допускаю работу с этим массивом как со статическим:
....
type
 PArrNodeSt = ^TArrNodeSt;
 TArrNodeSt = packed array [0..0] of TNode;
....
 PArrNodeSt(Node)^[i] := ....

Вообще это дупустимо?

2)
Когда во внешней программе просчитывается этот алгоритм, то в файл с данными я записываю и кол-во элементов массива.
Поэтому в основной программе я выделяю память под этот массив при помощи GetMem (юзаю FastMM4).
Но при чтении этого массива как динамического (x := Node[i]), иногда возникают ошибки. Ошибки происходят в ф-ии модуля System @DynArrayClear (@FreeMem).
Как это понимать? При обычном чтении динамического массива происходит обращение к ф-иям выделения/освобождения памяти?

Теперь при любом методе выделения памяти под массив работаю с ним как со статическим массивом. Это допустимо?


GrayFace   (2007-02-06 19:28:00) [1]

Erik2   (05.02.07 17:38) [40]
Помоему всем уже не до вопроса. Как я понял основная проблема во втором варианте это излишнее выделение памяти. Это легко обойти, можно использовать тотже механизм, что и TList.

Если нужно активное расширение массива, то можно вообще обойтись без реаллокации. Правда, доступ к элементам чуть-чуть замедлится.


Desdechado   (2007-02-06 12:31:00) [2]

А если картечью? :)

ЗЫ каждому свое


evvcom   (2007-02-06 12:05:00) [3]

> [42] Desdechado ©   (06.02.07 11:50)
> forever

Слишком категорично. Ситуевины разные бывают. Иногда просто нет смысла из пушки по воробьям.


Desdechado   (2007-02-06 11:50:00) [4]

Anatoly Podgoretsky ©   (05.02.07 20:18) [41]
Спасибо, но вы повторяете begin...end ©   (05.02.07 15:56) [39].
Выводы я сделал. Остаюсь при своих приоритетах - TList forever.


Anatoly Podgoretsky   (2007-02-05 20:18:00) [5]

> Desdechado  (05.02.2007 11:59:35)  [35]

Многомерных динамических массивов не бывает, бывает только array of type
Type может быть другим массивом.
Для удобства Борланд иммитирует многомерные массивы, но в отличии от не динамических, многомерный массив может быть не прямоугольным, вполне возможен такой массив

a
a b
a b c

Размещение памяти для любого массива последовательное. Каждый массив не зависим.
Остальные выводы сделаешь сам, на основе данной информации.


Erik2   (2007-02-05 17:38:00) [6]

To SH@RK
Помоему всем уже не до вопроса. Как я понял основная проблема во втором варианте это излишнее выделение памяти. Это легко обойти, можно использовать тотже механизм, что и TList. Но распределяет память динамически, но обращатся можно по элементам масива!


begin...end   (2007-02-05 15:56:00) [7]

> Desdechado ©   (05.02.07 15:23) [38]

В случае многомерных динамических массивов для каждого array of array (массива указателей на тела вложенных массивов) и для каждого array of TSomeType (массива максимальной вложенности) будут выделены непрерывные блоки памяти.

Например, вызвав SetLength(A, 2, 2)для A: array of array of Integer, получим 3 независимо выделенных блока памяти: один -- для массива A, который содержит два указателя, и два -- для тел вложенных массивов A[0] и A[1].


Desdechado   (2007-02-05 15:23:00) [8]

> соответственно массив нулевого уровня храни указатели на массивы первого и т. д.
Это и ежу понятно. Память по каким правилам под них выделяется?


Leff   (2007-02-05 15:15:00) [9]

> Т.е. всё же возможна сегментация !?
> Теперь не буду смешивать данные методы выделения и работы
> с памятью.
>
> ЗЫ. Теперь при возможности буду юзать GetMem, а если это
> не возможно, то списками.


Где в цитированном куске указано что возможна сегментация? Там как-раз говорится о том что данные хранятся последовательно и непрерывно в пределах одного динамического массива


Однако интересен вопрос с динамическими многомерными (разной размерности) массивами. Там-то как размерности в памяти лежат? В порядке объявления или в порядке выделения? Каждая размерность в произвольном месте памяти или таки в общем непрерывном куске?


многомерный динамический массив - это array of array of array ... of type, соответственно массив нулевого уровня храни указатели на массивы первого и т. д.


OSA   (2007-02-05 13:50:00) [10]


> Dynamic Array Types
> On the Win32 platform, a dynamic-array variable occupies
> four bytes of memory which contain a pointer to the dynamically
> allocated array. When the variable is empty (uninitialized)
> or holds a zero-length array, the pointer is nil and no
> dynamic memory is associated with the variable. For a nonempty
> array, the variable points to a dynamically allocated block
> of memory that contains the array in addition to a 32-bit
> length indicator and a 32-bit reference count. The table
> below shows the layout of a dynamic-array memory block.
> Dynamic array memory layout (Win32 only) Offset  Contents
>  
> -8
> 32-bit reference-count
>
> -4
> 32-bit length indicator (number of elements)
>
> 0..Length * (size of element) -1
> array elements


Т.е. всё же возможна сегментация !?
Теперь не буду смешивать данные методы выделения и работы с памятью.

ЗЫ. Теперь при возможности буду юзать GetMem, а если это не возможно, то списками.


Desdechado   (2007-02-05 11:59:00) [11]

Похоже, что я действительно фигню сморозил. Однако фразу из [12] повторю: "считаю, что нечего смешивать механизмы прямого доступа по адресу с нормальными языковыми конструкциями."
Такие вещи я делал и люблю делать на Си, но на паскале это, имхо, противоестественно. Не его это механизмы. Имхо.

ЗЫ Однако интересен вопрос с динамическими многомерными (разной размерности) массивами. Там-то как размерности в памяти лежат? В порядке объявления или в порядке выделения? Каждая размерность в произвольном месте памяти или таки в общем непрерывном куске? А то ведь при изменении размерности какого-нибудь серединного массива происходит ли перевыделение памяти на весь массив целиком?
Думаю, этих проблем достаточно, чтобы забить на динамические массивы и использовать списки. Имхо, они гораздо гибче, легче по ресурсам и понятнее. И там нет таких подводных камней, всё в руках твоих, а не спрятано в недрах компиляторных фишек.


Суслик   (2007-02-05 01:29:00) [12]


> Desdechado ©   (31.01.07 15:18) [10]
> Врать не буду, но имхо не стоит особенно расчитывать на
> то, что новые элементы динамического массива располагаются
> последовательно и строго за старыми. Внутренняя реализация
> скорее напоминает список, в который помять может выделяться
> произвольными кусками в произвольных местах, что очень сильно
> зависит от фрагментации памяти и от работы менеджера памяти.
>  А менеджеры у разных версий разные, а можно и вообще свои
> подключать.


О чем речь вообще - почитай доку - там четко сказано, что такое дин. массивы и как они хранятся. Это специфицировано и весьма четко. Доку я, кстати, привел.


Суслик   (2007-02-05 01:26:00) [13]

Ну чо ты придираешься, будто удовольствие получаешь.
Один из завсегдатаев сморозил жуткую фигню.
Я возмутился. Что - нельзя?
-----
Если по сути вопроса, то, ответ "конечно" - именно компилятор вставляет вызовы методов управлению памяться, где это нужно.


Германн   (2007-02-05 01:23:00) [14]


> Суслик ©   (05.02.07 01:17) [31]
>
> Дин массив - указатель на массив, к которому применяется
> compiler magic.
> Т.е. компилятор берет на себя управление выделенной памятью.
>  

И перераспределением выделенной памяти в рантайме тоже занимается компиллятор?


Суслик   (2007-02-05 01:17:00) [15]

Дин массив - указатель на массив, к которому применяется compiler magic.
Т.е. компилятор берет на себя управление выделенной памятью.


Суслик   (2007-02-05 01:15:00) [16]

Братцы с опытом, что вы такое говорите?
Почитайте memory manegement в хелпе.
В крайнем случае CPU посмотрите.

Что стало модно такие ответы давать. Вот для справки "лентяям":

Dynamic Array Types
On the Win32 platform, a dynamic-array variable occupies four bytes of memory which contain a pointer to the dynamically allocated array. When the variable is empty (uninitialized) or holds a zero-length array, the pointer is nil and no dynamic memory is associated with the variable. For a nonempty array, the variable points to a dynamically allocated block of memory that contains the array in addition to a 32-bit length indicator and a 32-bit reference count. The table below shows the layout of a dynamic-array memory block.
Dynamic array memory layout (Win32 only) Offset  Contents  
-8
32-bit reference-count

-4
32-bit length indicator (number of elements)

0..Length * (size of element) -1
array elements


GrayFace   (2007-02-04 22:59:00) [17]

DevilDevil ©   (31.01.07 13:24) [5]
Так наверное правильнее:

Без разницы.

Сергей М. ©   (31.01.07 13:28) [7]
Динамические придуманы для лентяев и батонокидателей)

Зря ты смайлик не дорисовал, а то ведь поверить могут. :)

evvcom ©   (31.01.07 15:42) [13]
До D7 включительно именно так и располагаются.

Хоть я и не смотрел D8-D2006, но после D7 это тоже наверняка так.

jack128 ©   (01.02.07 0:35) [24]
Почему нафиг??  С New/GetMem - гораздо больше ошибок огребешь, чем с дин массивами

+1


Джо   (2007-02-01 14:26:00) [18]

> [27] reonid ©   (01.02.07 12:47)
> 2SH@RK ©   (31.01.07 16:24) [21]
> >При использовании в D7+FastMM4 динамического массива память
> для него >выделяется последовательно.
>
> Для гренландских голубых китов коэффициент Пи обычно считается
> равным 3.1416 ...

Вы ошиблись, это константа для арктических пингвинов.


reonid   (2007-02-01 12:47:00) [19]

2SH@RK ©   (31.01.07 16:24) [21]
>При использовании в D7+FastMM4 динамического массива память для него >выделяется последовательно.

Для гренландских голубых китов коэффициент Пи обычно считается равным 3.1416 ...


umbra   (2007-02-01 12:15:00) [20]


> Я не чётко понимаю работу с динамическими массивами. Как
> под них выделяется память?

http://www.rsdn.ru/?article/Delphi/dynarrays.xml


Страницы:   1 2 3

Наверх

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