Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.05;
Скачать: CL | DM;

Вниз

Быстрое выделение памяти и быстрая её очистка   Найти похожие ветки 

 
Maks Realov   (2004-08-22 10:44) [0]

Здравствуйте. Не могу понять как добиться быстрого распределения памяти под n-ое кол-во структур. Ведь делать New в цикле для каждой структуры - не рационально с точки зрения использования менеджера памяти Delphi. Проще говоря - долго. Поясню на примере:

 // имеем структуру (в реале она гораздо больше)
 PTRecMy = ^TRecMy;
 TRecMy = record
   bTest: boolean;
   sTest: string[16];
 end;

 // имеем динамический массив указателей
 TMyList = array of PTRecMy;

// Как можно сделать:
procedure TForm1.GetMemForStructs(Sender: TObject);
const
 iSize = 32;
var
 MyList: TMyList;
 i: integer;
begin
 SetLength(MyList, iSize);
 for i:= 0 to Length(MyList)-1 do
 begin
   New(MyList[i]); // для каждого элемента индивидуально распред. память
   MyList[i]^.sTest:= IntToStr(i);
   // заполняю структуру
 end;
 // doing somthing
 for i:= 0 to Length(MyList)-1 do
   Dispose(MyList[i]); // освобождаю память от каждого эл-та

 MyList:= nil;
end;

// Как хотелось бы сделать:
procedure TForm1.GetMemForStructs2(Sender: TObject);
const
 iSize = 32;
var
 MyList: TMyList;
 i: integer;
 pStart: pointer;
begin
 SetLength(MyList, iSize);  // устанавл. размер массива указателей
 GetMem(pStart, SizeOf(TRecMy)*iSize);  // резервирую память достаточную для всех структур
 Initialize(pStart, SizeOf(TRecMy)*iSize);

 // а потом в цикле просто произвожу присвоение указателей на места в выделенной памяти
 for i:= 0 to Length(MyList)-1 do
   Pointer(MyList[i]):= Pointer(pStart+i*SizeOf(TRecMy)); // - тут ошибка
 // Хотя если сделать так, то компилятор не орёт, что ему плохо:
 MyList[i]:= pStart;

 // И освобождение тоже было бы быстрым
 FreeMem(pStart);
 MyList:= nil;
end;

Почему паскалевский компилятор не даёт прибавить к указателю значение? Или я что-то не так делаю?
Подскажите пожалуйста.


 
TUser ©   (2004-08-22 11:34) [1]

Вычислять значение указателся в паскале можно, но Паскаль требует явного преобразования типов. Указатель - это не число (с точки зрения компилятора), поэтому сами по себе указатели складывать нельзя. А вот, если преобразовать к другому типу, для которого определено + и - - то все будет Ок. Например так
procedure TForm1.Button1Click(Sender: TObject);
var P:^integer;
   i,j:integer;
begin
  GetMem(P,3*sizeof(integer));
  try
   for i:=0 to 2 do begin
      P^:=i;
      P:=Pointer(longint(P)+sizeof(integer));
      end;
   P:=Pointer(longint(P) - 3*sizeof(integer));
   j:=0;
   for i:=0 to 2 do begin
      j:=j+P^;
      P:=Pointer(longint(P)+sizeof(integer));
      end;
   Caption:=inttostr(j);
   P:=Pointer(longint(P) - 3*sizeof(integer));
  finally
   FreeMem(P);
  end;
end;


 
Anatoly Podgoretsky ©   (2004-08-22 13:10) [2]

TMyList = array of ТTRecMy;
И никакого своего выделения и освобождения. А так кроме затрат на это ты еще и тратишь 4 байта на указатель.


 
TUser ©   (2004-08-22 13:13) [3]

Признаюсь, что мы ошиблись. Анатолию еще не надоело отвечать по существу.


 
Рыба ©   (2004-08-22 14:21) [4]

>TUser ©  (22.08.04 13:13) [3]

Есть ещё порох! :-)))))))


 
Maks Realov   (2004-08-22 17:25) [5]

2 Anatoly Podgoretsky ©   (22.08.04 13:10) [2]:
Спасибо. Вполне разумно получается! Хоть и непривычно как-то, надо признаться. Но я так и не понял - что за проблемы с адресной арифметикой? Ведь предложенный мной второй способ вполне легален. Что там TUser говорил про то, что указатели складывать нельзя (что нельзя напрямую - сам убедился. Дичь.)?


 
TUser ©   (2004-08-22 19:00) [6]


> TUser говорил про то

что Паскать - строго типизированный язык. Указатель - это не число, это просто указатель. Над ним не определены операции сложения и вычитания (Точнее - не определена бинарная операция сложения, если первый операнд - указатель, а второй - integer). Поэтому при выволнении арифметических действий на указателями надо их приводить у типу longint.


 
Mim1 ©   (2004-08-22 20:22) [7]

Указатели разные бывают.

Character-pointer operators
Operator Operation Operand types Result type Example
+ pointer addition character pointer, integer character pointer P + I
- pointer subtraction character pointer, integer character pointer, integer P - Q
^ pointer dereference pointer base type of pointer P^
= equality pointer Boolean P = Q
<> inequality pointer Boolean P <> Q


 
Mim1 ©   (2004-08-22 20:23) [8]

Например

var p:pchar;
begin
 p := "alpha";
 p := p + 2;
 ShowMessage(p);
end;



Страницы: 1 вся ветка

Текущий архив: 2004.09.05;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.046 c
3-1092034532
Mitrofan
2004-08-09 10:55
2004.09.05
Firebird + Interbase на одном компьютере


1-1092755690
pavel_pavel
2004-08-17 19:14
2004.09.05
Чтение файла посимвольно


6-1088490331
leonidus
2004-06-29 10:25
2004.09.05
Компонент idHTTP не работает через прокси


1-1092888489
Fktrc
2004-08-19 08:08
2004.09.05
Потоки при завершении приложения


6-1087730110
amoral
2004-06-20 15:15
2004.09.05
У кого есть примеры/доки по написаню Proxy,Firewall, и про NDIS