Текущий архив: 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