Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как работают массивы в Delphi. 
:(
    Опции темы
devmstr
  Дата 21.12.2004, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 28.4.2004
Где: Ukraine

Репутация: 2
Всего: 11



Как работают массивы в Delphi.

Тут назрел такой вопрос, что конкретно делает Delphi при вызове SetLength(), и увеличении числа элементов. Есть предположение, что Delphi выделяет новый участок памяти, и копирует все элементы туда...

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


--------------------
Think different ©Steve Jobs 
user posted image
PM MAIL WWW   Вверх
AntonSaburov
Дата 21.12.2004, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: нет
Всего: 118



Вопрос как-то мало понятен. Что именно надо узнать ?
PM MAIL WWW ICQ   Вверх
devmstr
Дата 21.12.2004, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 28.4.2004
Где: Ukraine

Репутация: 2
Всего: 11



Цитата(AntonSaburov @ 21.12.2004, 18:35)
Вопрос как-то мало понятен. Что именно надо узнать ?

Что конкретно делает Delphi при вызове SetLength(), и увеличении числа элементов
smile


--------------------
Think different ©Steve Jobs 
user posted image
PM MAIL WWW   Вверх
Vit
Дата 21.12.2004, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 48
Всего: 207



Цитата(magician @ 21.12.2004, 11:43)
Что конкретно делает Delphi при вызове SetLength(), и увеличении числа элементов



Выделяет память в нужном количестве.


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Zero
Дата 22.12.2004, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2169
Регистрация: 23.10.2004
Где: Россия, г. Рязань

Репутация: 8
Всего: 24



Цитата(Vit @ 21.12.2004, 23:46)
Выделяет память в нужном количестве.

Vit, помоему ты не так понял, а может я. Но ИМХО magician, спрашивал каким образом функция выделяет память.
Цитата(magician @ 21.12.2004, 18:23)
что конкретно делает Delphi при вызове SetLength(), и увеличении числа элементов. Есть предположение, что Delphi выделяет новый участок памяти, и копирует все элементы туда...


PM MAIL ICQ   Вверх
Bes
Дата 22.12.2004, 07:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 5
Всего: 7



А вообще существует ли механизм "увеличить" зарезервированную память?
Наверное она может резервироваться в определенном размере и освобождаться.
PM MAIL   Вверх
~FoX~
Дата 22.12.2004, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 13
Всего: 68



Код

procedure DynArraySetLength(var a: Pointer; typeInfo: Pointer; dimCnt: Longint; lengthVec: PLongint);
var
 i: Integer;
 newLength, oldLength, minLength: Longint;
 elSize: Longint;
 neededSize: Longint;
 p, pp: Pointer;
begin
 p := a;

 // Fetch the new length of the array in this dimension, and the old length
 newLength := PLongint(lengthVec)^;
 if newLength <= 0 then
 begin
   if newLength < 0 then
     Error(reRangeError);
   DynArrayClear(a, typeInfo);
   exit;
 end;

 oldLength := 0;
 if p <> nil then
 begin
   Dec(PLongint(p));
   oldLength := PLongint(p)^;
   Dec(PLongint(p));
 end;

 // Calculate the needed size of the heap object
 Inc(PChar(typeInfo), Length(PDynArrayTypeInfo(typeInfo).name));
 elSize := PDynArrayTypeInfo(typeInfo).elSize;
 if PDynArrayTypeInfo(typeInfo).elType <> nil then
   typeInfo := PDynArrayTypeInfo(typeInfo).elType^
 else
   typeInfo := nil;
 neededSize := newLength*elSize;
 if neededSize div newLength <> elSize then
   Error(reRangeError);
 Inc(neededSize, Sizeof(Longint)*2);

 // If the heap object isn't shared (ref count = 1), just resize it. Otherwise, we make a copy
 if (p = nil) or (PLongint(p)^ = 1) then
 begin
   pp := p;
   if (newLength < oldLength) and (typeInfo <> nil) then
     FinalizeArray(PChar(p) + Sizeof(Longint)*2 + newLength*elSize, typeInfo, oldLength - newLength);
   ReallocMem(pp, neededSize);
   p := pp;
 end
 else
 begin
   Dec(PLongint(p)^);
   GetMem(p, neededSize);
   minLength := oldLength;
   if minLength > newLength then
     minLength := newLength;
   if typeInfo <> nil then
   begin
     FillChar((PChar(p) + Sizeof(Longint)*2)^, minLength*elSize, 0);
     CopyArray(PChar(p) + Sizeof(Longint)*2, a, typeInfo, minLength)
   end
   else
     Move(PChar(a)^, (PChar(p) + Sizeof(Longint)*2)^, minLength*elSize);
 end;

 // The heap object will now have a ref count of 1 and the new length
 PLongint(p)^ := 1;
 Inc(PLongint(p));
 PLongint(p)^ := newLength;
 Inc(PLongint(p));

 // Set the new memory to all zero bits
 FillChar((PChar(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0);

 // Take care of the inner dimensions, if any
 if dimCnt > 1 then
 begin
   Inc(lengthVec);
   Dec(dimCnt);
   for i := 0 to newLength-1 do
     DynArraySetLength(PPointerArray(p)[i], typeInfo, dimCnt, lengthVec);
 end;
 a := p;
end;

procedure _DynArraySetLength;
asm
{       PROCEDURE _DynArraySetLength(var a: dynarray; typeInfo: PDynArrayTypeInfo; dimCnt: Longint; lengthVec: ^Longint) }
{     ->EAX     Pointer to dynamic array (= pointer to pointer to heap object) }
{       EDX     Pointer to type info for the dynamic array                     }
{       ECX     number of dimensions                                           }
{       [ESP+4] dimensions                                                     }
       PUSH    ESP
       ADD     dword ptr [ESP],4
       CALL    DynArraySetLength
end;

procedure _DynArrayCopy(a: Pointer; typeInfo: Pointer; var Result: Pointer);
begin
 if a <> nil then
   _DynArrayCopyRange(a, typeInfo, 0, PLongint(PChar(a)-4)^, Result)
 else
   _DynArrayClear(Result, typeInfo);
end;


Вот как оно работает.


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
NiJazz
Дата 22.12.2004, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Jazz coder
****


Профиль
Группа: Экс. модератор
Сообщений: 2286
Регистрация: 10.8.2003
Где: Москва

Репутация: 6
Всего: 23



~FoX~
Это так сложно сделать? smile
А есть в Delphi возможность работы с дин. масивами с помощью LocalAlloc, LocalReAlloc и LocalFree?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0483 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.