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

Вниз

Массивы   Найти похожие ветки 

 
nimble ©   (2002-07-06 01:44) [0]

Вопрос такоко плана, есть запись типа:
TRec = rec
i: Integer;
r: Real;
s: String[30];
ch: Char;
end;

И массивчик ->mas: array[10001..65000] of TRec;
Из этого массивчика будет max"ум использовано 3000 записей, хотя памяти выделено на 65000-10001, явная неэкономия.
Как быть?


 
Pat ©   (2002-07-06 01:46) [1]

Используй динамический массив


 
nimble ©   (2002-07-06 01:56) [2]

Ну а если мне нужно обратиться, скажем, к 45321"му элементу массива, мне придется делать цикл, а так сразу обратился. Я читал что в таких ситуациях используют VirtualAloc. Есть соображения?


 
NailMan ©   (2002-07-06 02:20) [3]

Используй динамический ограниченный массив

Пример:
Я делал проект как консольное приложение

type
TRec = record
i: Integer;
r: Real;
s: String[30];
ch: Char;
end;
Tmas = array[10001..65000] of TRec;

var
Mas : ^TMas;

begin
GetMem(Mas,Sizeof(TRec)*3000);
Mas^[10010].s:="Vasya Pupkin";
Writeln(Mas^[10010].s);
readln;
FreeMem(Mas);
end.

Итог работы : "Vasya Pupkin"

Вуаля!


 
nimble ©   (2002-07-06 02:25) [4]

->NailMan
Выглядит шикарно! Нуна попробовать, спасибо за инфо!


 
nimble ©   (2002-07-06 02:33) [5]

И тут же в догонку такой вопрос, вот в примере выше выделяется память под 3000 элементов, а я ведь не знаю сколько их на самом деле. Как тут быть?


 
nimble ©   (2002-07-06 02:55) [6]

->NailMan
К сожалению, если выделяю память на 3000 элементов, как в примере, а нужно обратиться к 3001, то ничего не выходит:(!!!


 
Aleks1   (2002-07-06 03:06) [7]

2 nimble ©
Попробуй заменить TRec = record
на TRec = class(TObject)
и храни их в TList.


 
nimble ©   (2002-07-06 03:13) [8]

->Aleks1
С объектами небольшая напряженко, как потом с ним работать?


 
NailMan ©   (2002-07-06 03:20) [9]

Вообще память не жалей(все равно МД разберется с ней как надо).
Если не знаешь сколько будет элементов делай так:

Var P:pointer;
Elem:^TRec;

GetMem(p,2 * 1024 * 1024);
Elem:=p; //Ремапнули элемент на кэш(фактически РЕСЕТ)
Inc(Elem,3001); //Обращаемся к 3001му элементу
Elem^.s:="Vasya Pupkin - Special For Master of Delphi";
А если надо в цикле заполнять:
Elem:=p;
For i:=0 to N do
Begin
Elem^.s:=Inttostr(i); //что-то делаем
....
Inc(Elem);
End;

Выгоды
- Работать в принципе должно быстрее нежели если массив-фактическая переменная,
- Элементов хоть мульон,
- Кэш можно использовать несколькими структурами, по аналогичному принципу(если надо сохраняй его на винт в файл).


Еще вопросы?


 
Aleks1   (2002-07-06 03:21) [10]

Ну как? А молча.
TRec(MyList.Items[i]).ch:=#32;
или MyRealValue:=TRec(MyList.Items[i]).r;


 
nimble ©   (2002-07-06 03:31) [11]

->NailMan
Объясни, плз, первую строчки:
GetMem(p,2 * 1024 * 1024);
Не вкуриваю ее предназначение!
->Aleks1
А ты че такой нервный?


 
Aleks1   (2002-07-06 03:36) [12]

2 nimble © (06.07.02 03:31)
Ты чё? Все мои знакомые утверждают, что такой флегмы как я, они никогда, нигде не встречали!


 
nimble ©   (2002-07-06 03:45) [13]

->Aleks1
Я с объетками редко встречался, поэтому многово недопонимаю. Я тебя переспросил,а ты в штыки :)


 
NailMan ©   (2002-07-06 04:01) [14]

GetMem(p,2 * 1024 * 1024);
Выделяем поинтеру 2 метрабайта памяти

FreeMem(P); Мочим его

Остальное ясно?

To Aleks1>
А зачем в простой программе надо какие-то объекты, листы и прочее Items?

Лишняя память имхо + тормоза + излишество


 
Aleks1   (2002-07-06 04:03) [15]

2 nimble © (06.07.02 03:45)
> Я тебя переспросил,а ты в штыки :)
Ну, ведь ты же переспросил о моих нервах, так я же и ответили о них :)
> Я с объетками редко встречался, поэтому многово недопонимаю.
...
Ну может лучше уйти в управдомы? Без знания "объетков" - с Дельфи лучше не связывать свое будущее.


 
Aleks1   (2002-07-06 04:10) [16]

2 NailMan © (06.07.02 04:01)
>To Aleks1>
>А зачем в простой программе надо какие-то объекты, листы и прочее Items?
>Лишняя память имхо + тормоза + излишество

> Выделяем поинтеру 2 метрабайта памяти... ???
Ну и у кого же лишняя память? И у кого же тормоза?


 
NailMan ©   (2002-07-06 04:40) [17]

Если у него Win2k то лишняя память должна быть по определению.

А тормоза будут если прога будет обращаться N число раз в сек, где N стремится к очень большим числам.
Обычный поинтер это тебе не класс.

К сведению, команда х86 средней длины декодируется процессорм Атлон за 17 тактов, а П4 еще дольше(я уже не говорю об самом исполнении).
А при обращении к классу таких командочек обрабатывается о-го-го, не в пример ежели обращаться к поинтеру.


 
Aleks1   (2002-07-06 05:00) [18]

Дык я же не о том, а

>nimble © (06.07.02 02:33)
И массивчик ->mas: array[10001..65000] of TRec;
Из этого массивчика будет max"ум использовано 3000 записей, хотя памяти выделено на 65000- 10001, явная неэкономия.
Как быть?

И ещё.
>nimble © (06.07.02 02:33)
И тут же в догонку такой вопрос, вот в примере выше выделяется память под 3000 элементов, а я ведь не знаю сколько их на самом деле. Как тут быть?

Ну и как тут быть без списка? Или динамического массива?

Ну и ещё.
Inc(Elem); - что это такое? Либо я отстал в освоении новых версий Дельфи, либо это - увеличение на 1, что явно "НЕ ТО".


 
NailMan ©   (2002-07-06 05:15) [19]

To Aleks1->
> Ну и ещё.Inc(Elem); - что это такое? Либо я отстал в освоении новых >версий Дельфи, либо это - увеличение на 1, что явно "НЕ ТО".

Если Elem - поинтер на структуру(Elem:^TRec), Inc(Elem) приводит к смещению(увеличению адреса в Elem) на Sizeof(Trec), тоесть
фактически будет аналогично mas[i+1]

И это явно то что я имел в виду под оператором Inc(Elem);


 
TTCustomDelphiMaster ©   (2002-07-06 08:59) [20]

Во времена охоты на птиродактелей, когда я начинал писать на basic"е в этих случаях я делал так:
создаем динамический массив mas of Trec и массивчик index [10001..65000] of word
Если нужно внести сорокпятьтысячпетсотшестой элемент добавляеш запись в динамический массив а в массив index[45506] = номеру добавленой записи в динамическом массиве.

Итого:
Перерасход памяти (65000-10001)*2 байт < 128 кБайт
Инструментарий на уровне детского сада :))))


 
nimble ©   (2002-07-07 03:31) [21]

Ладно, тогда такой вопрос: нужно выделить память под 3 записи и так чтобы к первому обращался с индексом 10001, ко второму - 12121, ну а к третьему - 45002. Вот как это сделать.
->To Aleks1
По поводу объетков, ты серьезно все воспринимаешь.


 
Aleks1   (2002-07-07 04:33) [22]

Насчет серьезности - просто я порой забываю рисовать смайлики.
А вот насчет конкретно вопроса???
Точно могу сказать, что понятие "индекс" тут никак не пройдет. Нужно искать другой путь.
Может быть стоит подробнее описать задачу?


 
nimble ©   (2002-07-07 06:31) [23]

> Может быть стоит подробнее описать задачу
Имеется список судов, чей код лежит в пределе от 10001 до 65000.
К каждому судно прилепляется куча параметров: название, ширина, длина и т.п. И если мне нужно получить инфо, скажем, по судну с кодом 45321, то при использовании дин. массива потребуется цикл, чего очень не хочется. А так, указал mas[45321].название и ВУАЛЯ!


 
MBo ©   (2002-07-07 07:09) [24]

путь 1: Хэш (hash) списки или массивы

2: Сводишь записи в сортированный по нужному полю, т.е. номеру, список, двоичный поиск по 3000 записей - всего ~12 сравнений.


 
leshy   (2002-07-08 10:30) [25]

Настоятельно рекомендую: никогда не делайте динамических массивов не с нуля — некрасиво. Это раз.
Второе: сохранить размер выделяемого массива после его создания — это что, проблема? Или лень?
И последнее: если вы не уверены, что количество данных в массиве конечно, тогда объявляйте
type
PArray = ^TArray;
TArray = array[0..0] of TRec;

и работайте с PArray а не с TArray: создайте фунуцию ReallocArray, в которую передавайте количество записей, чтобы оно сохранялось в глобальной переменной.

А а если количество данных конечно, тогда тоже объявление, потом
hFile := CreateMapping($FFFFFFFF...
Pointer(lpArray) := MapViewOfFile(hFile...
CloseHandle(hFile)
и работайте с этим массивом в свопе. Если данные храняться в файле, то вместо $FFFFFFFF хандле файла.
Для сортировки можно использовать TList — заполнить адресами элементов (@lpArray[I]) и сделать QuickSort.

А самое грамотное — приделать к этому всему движок, простой потомок TObject с полями P: PArray и FCount: integer, и методом ReallocArray. Плюс property Items[Index: integer]: TRec read ...; default; И не полоскать мозги.


 
Vitaly ©   (2002-07-08 11:38) [26]

nimble! MBo © (07.07.02 07:09) дело говорит.
Проще всего TList.indexOf (TList.sorted = true)


 
TTCustomDelphiMaster ©   (2002-07-08 12:03) [27]


> nimble © (06.07.02 01:44)

Твоя задача легко решается если использовать базу данных.


 
nimble ©   (2002-07-09 04:20) [28]

А что даст использование VirtualAlloc?


 
nimble ©   (2002-07-09 04:36) [29]

А как насчет такого объявления
mas: array [10001..65000] of Array of TRec?


 
Yuri-7   (2002-07-09 09:25) [30]


1.>Aleks1
Для работы с TList совсем не нужно record заменять на TObject.

2.> nimble
Когда ты объявляешь большой массив, это не значит, что ты занял какую-то память. Только когда ты начинаешь работать с элементами, тогда выделяется память.
Для твоей задачи нужно добавить в record номер и использовать TSortList.


 
Anatoly Podgoretsky ©   (2002-07-09 09:42) [31]

О чем ты беспокоишьс об 2.3 мегабайте, нет смысла усложнять жизнь, статический массив.



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

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

Наверх




Память: 0.54 MB
Время: 0.014 c
4-58363
МишА
2002-05-15 20:42
2002.07.18
SendMessage в Dos приложение


1-58066
werr
2002-07-05 17:04
2002.07.18
Как узнать каким юзером занят файл?


14-58256
Alessio
2002-06-18 22:17
2002.07.18
Рассуждения по теме совместного проекта


14-58321
koty
2002-06-19 02:21
2002.07.18
Прогамирование в Delphi под Dos


1-58045
Славик
2002-07-07 16:42
2002.07.18
Как удалить строку из ListBox?