Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
3-100178
edst
2003-03-13 09:12
2003.03.31
Где находится isc4.gdb в Linux


1-100265
Dracula2000
2003-03-18 12:00
2003.03.31
Запуск с параметром!


6-100362
k-sergey
2003-02-07 08:14
2003.03.31
Где то видел пример проги - установка DialUp соединения


3-100183
gmkushkunov
2003-03-11 21:40
2003.03.31
Delphi 7 и SQL Server 2000


3-100160
td
2003-03-12 23:13
2003.03.31
как сжать таблицу





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский