Форум: "Основная";
Текущий архив: 2003.03.31;
Скачать: [xml.tar.bz2];
ВнизВыделение памяти Найти похожие ветки
← →
{bas} (2003-03-17 11:01) [0]Как правильно выделить память для указателя на массив записей??
Я делаю так:
type
RMetaStockRecord = record
period : String;
time : TDateTime;
rate : double;
volume : integer;
end;
RMetaStockList = array[0..500000] of RMetaStockRecord;
PMetaStockList = ^RMetaStockList;
TMetaStockList = class(TObject)
private
{ Private declarations }
FList : PMetaStockList;
FCount : integer;
public
{ Public declarations }
procedure Add(peroid: String; time: TDateTime; rate: double; volume: integer);
end;
..................
procedure TMetaStockList.Add(peroid: String; time: TDateTime; rate: double; volume: integer);
begin
// вот так выделяю память, но что очень много выделяется
// до 10МБ на 50 записей
// КАК ЖЕ ВСЕ ТАКИ ПРАВИЛЬНО ЗДЕСЬ СДЕЛАТЬ ?
ReallocMem(FList, (length(FList^)+1)*sizeOF(RMetaStockRecord));
//
Flist^[Fcount].period := peroid;
Flist^[Fcount].time := time;
Flist^[Fcount].rate := rate;
Flist^[Fcount].volume := volume;
inc(Fcount);
end;
← →
icWasya (2003-03-17 11:37) [1]а сколько будет
(length(FList^)+1)*sizeOF(RMetaStockRecord))
????? Как раз и 10М. Скорее всего нужно((FCount+1)*sizeOF(RMetaStockRecord))
.
← →
{bas} (2003-03-17 11:59) [2]>> icWasya ©
Нет так не получается, при попытке записать в переменные рекорда говорит Access vialation... Read at address ..... Причем после выделения памяти для 3ей записи в массиве.
>> All
Подсмотрел я как делается в TStringList, но не понял откуда они бирут числа 4, 8 и так далее .... и что ставить в моем случае
type
PStringItem = ^TStringItem;
TStringItem = record
FString: string;
FObject: TObject;
end;
PStringItemList = ^TStringItemList;
TStringItemList = array[0..MaxListSize] of TStringItem;
TStringList = class(TStrings)
private
FList: PStringItemList;
FCount: Integer;
FCapacity: Integer;
procedure Grow;
protected
procedure SetCapacity(NewCapacity: Integer); override;
public
function Add(const S: string): Integer; override;
end;
......
procedure TStringList.Grow;
var
Delta: Integer;
begin
if FCapacity > 64 then Delta := FCapacity div 4 else
if FCapacity > 8 then Delta := 16 else
Delta := 4;
SetCapacity(FCapacity + Delta);
end;
procedure TStringList.SetCapacity(NewCapacity: Integer);
begin
ReallocMem(FList, NewCapacity * SizeOf(TStringItem));
FCapacity := NewCapacity;
end;
procedure TStringList.InsertItem(Index: Integer; const S: string);
begin
if FCount = FCapacity then Grow;
with FList^[Index] do
begin
Pointer(FString) := nil;
FObject := nil;
FString := S;
end;
Inc(FCount);
Changed;
end;
← →
{bas} (2003-03-17 15:03) [3]ну что - никто не делал так??
← →
theodor_iv (2003-03-17 16:04) [4]
> {bas} © (17.03.03 15:03)
Ты не указал, как ты создаешь FList. Не процедурой New случайно? Тогда и должна выделяться память под весь массив, т.е. 12М.
← →
SVM (Perm) (2003-03-17 16:06) [5]period : ShortString;
← →
Владислав (2003-03-17 16:57) [6]Посчитай, сколько места в памяти занимает твоя запись, умножь полученное на 500000. По моему, порядок полученного числа в норме. Чего ты удивляешься?
← →
{bas} (2003-03-17 18:31) [7]ДА я не удивляюсь, я спрашиваю как правильно выделить память под
одну запись и прибавлять по одной записи в массиве для PMetaStockList?????
Потому что у меня не получилось все время выскакивал Access Vialation... Read at address....
и как правильно освободить
← →
cyborg (2003-03-17 21:46) [8]мдя :)
New(FList); Dispose(FList);
← →
alex55 (2003-03-17 23:00) [9]RMetaStockRecord = record
period : String;
time : TDateTime;
rate : double;
volume : integer;
end;
RMetaStockList = array[0..500000] of PMetaStockRecord;//RMetaStockRecord;
PMetaStockList = ^RMetaStockList;
TMetaStockList = class(TObject)
private
{ Private declarations }
FList : RMetaStockList;//PMetaStockList;
FCount : integer;
public
{ Public declarations }
procedure Add(peroid: String; time: TDateTime; rate: double; volume: integer);
! end;
..................
procedure TMetaStockList.Add(peroid: String; time: TDateTime; rate: double; volume: integer);
begin
// вот так выделяю память, но что очень много выделяется
// до 10МБ на 50 записей
// КАК ЖЕ ВСЕ ТАКИ ПРАВИЛЬНО ЗДЕСЬ СДЕЛАТЬ ?
GetMem(Flist[Fcount],sizeOF(RMetaStockRecord));
{ReallocMem(FList, (length(FList^)+1)*sizeOF(RMetaStockRecord));}
//
Flist{^}[Fcount]^.period := peroid;
Flist{^}[Fcount]^.time := time;
Flist{^}[Fcount]^.rate := rate;
Flist{^}[Fcount]^.volume := volume;
inc(Fcount);
end;
а освободить FreeMem...
← →
Sash! (2003-03-18 09:18) [10]Советую использовать для этого TList.
А для перераспределения памяти пользоваться ReallocMem
← →
{bas} (2003-03-18 10:05) [11]>>cyborg ©
я не хочу сразу отжирать много памяти, а New как раз этот делает. Я хочу динамически выделятьь при добавлении каждой записи
>>Sash!
Какой же SIZE выделять при каждом ReallocMem ????????????????
← →
Владислав (2003-03-18 10:33) [12]Блин, ну объяви ДИНАМИЧЕСКИЙ массив. И будет тебе счастье.
← →
{bas} (2003-03-18 10:45) [13]>>Владислав ©
Блин, да я хочу понять(разобратьтся) как выделить память в моем случае, потому что это одно из типовых решений - указатель на массив чего-либо(в моем случае рекорд)
← →
REA (2003-03-18 11:26) [14]1) Динамический массив
2) Список
3) Список классов
← →
chdv_1 (2003-03-18 13:36) [15]попробуй period: String[255]
← →
theodor_iv (2003-03-18 13:43) [16]
> {bas} © (17.03.03 11:01)
Твоя ошибка в строке
> ReallocMem(FList, (length(FList^)+1)*sizeOF(RMetaStockRecord));
т.к. FList -- это не динамический массив, length(FList^) всегда возвращает значение 500001.
Объяви FList: array of RMetaStockRecord и вместо ReallocMem пиши SetLength(FList, Length(FList) + 1);
Освободить простым SetLength(FList, 0);
← →
Style (2003-03-18 13:51) [17]PStringItem = ^TStringItem;
у тебя есть PStringItem вот и все
var
SItem: PStringItem;
GetMem(SItem, sizeof(TStringItem)+1);
Далее заполняй SItem и добавляй его в TList;
Не забудь сделать FreeMem на Дестрое!
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.03.31;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c