Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.11.27;
Скачать: [xml.tar.bz2];

Вниз

Как организовать индекс(отображение) для масива?   Найти похожие ветки 

 
Erik   (2003-11-18 10:56) [0]

Проблема заключается в наличии Array of MyRecord с Sub Array. Причем имеются разные масивы. Для сортировки я немудорствуя взял стандартный QuikSort. Возникла проблемма как работать с разными record? И невезде можно было на прямую получить значение.
Я сделел так, создал
RMapSort = record
pElement: Pointer; - указатель на элемент масива
GetValue: TGetElemValue; - адрес функции выдаюшей значение
end;
MapSort = Array of RMapSort;
Долее думаю понятно как я исползую данный Array.
Вопрос в том можно ли получить в GetValue значение непередавая ей указатель pElement? И насколько красиво данное решение есть ли изящнее?


 
Anatoly Podgoretsky   (2003-11-18 11:12) [1]

Красиво это делается через классы.


 
Владислав   (2003-11-18 11:13) [2]

Чтобы сделать изящнее, надо понят, чего ты вообще хотел получить. А пока только каша.
Есть ли изящнее? Да. Есть.


 
Anatoly Podgoretsky   (2003-11-18 11:26) [3]

Слова вроде все русские, а вот смысл не наш.


 
Erik   (2003-11-18 11:28) [4]

Тоесть лучше всего создать класс с масивом указателей на элементы моего масива и записать туда адресс функции которая может дать зачение элемента или сравнить два элемента?


 
Семен Сорокин   (2003-11-18 11:31) [5]

2Erik
TList тебе поможет


 
Владислав   (2003-11-18 11:35) [6]

"создать класс с масивом указателей на элементы моего масива"

То ли лыжи не едут... А чем же не подходит массив элементов?


 
Murad   (2003-11-18 11:46) [7]

Согласен с Семеном Сорокиным
Надо использовать TList и его метод Sort


 
Erik   (2003-11-18 12:42) [8]

Лучше свой напишу :), ну нелюблю я TList что тут можно поделать.


 
Digitman   (2003-11-18 13:07) [9]


> Erik


вот и зря) ... лучше бы ты с тем же рвением "не любил" разного рода динамические массивы, открытые массивы и иже с ним..

нет ничего хуже скрытности действий компилятора и накладных расходов, связанных с кодом, использующим такие массивы ... а-ля "массивы для лентяев и чайников"


 
kull   (2003-11-18 14:44) [10]

К сведению: TList в своей реализации тоже динамические массивы использует, и накладных расходов не боится.

Хотя я согласен, что пользоваться надо тем, что уже сделано (например TList), а не пытаться изобретать велосипед...


 
Digitman   (2003-11-18 14:49) [11]


> kull © (18.11.03 14:44) [10]



> TList в своей реализации тоже динамические массивы использует


где ты там какие-то динамические массивы углядел - ума не приложу.

нет там никаких дин.массивов, а есть явные операции по выделению/перераспределению/освобождению памяти


 
kull   (2003-11-18 15:01) [12]

Да, виноват, это я ошибся.

Но и с динамическими массивами работают те же операции по копированию и перемещению блоков памяти.
Какие там могут быть расходы? SetLength что ли? так это тоже самое что realloc...


 
Digitman   (2003-11-18 15:20) [13]


> kull


ты хоть бы вреализацию что ль взглянул) ... прежде чем беспредметно возражать)

про SetLength(), значит, речь ?

изволь !

вот эквивалент в TList


procedure TList.SetCapacity(NewCapacity: Integer);
begin
if (NewCapacity < FCount) or (NewCapacity > MaxListSize) then
Error(@SListCapacityError, NewCapacity);
if NewCapacity <> FCapacity then
begin
ReallocMem(FList, NewCapacity * SizeOf(Pointer));
FCapacity := NewCapacity;
end;
end;


заметь : один-единственный вызов ReallocMem ! и больше ничего, что хоть сколь-либо заметно влияло на производительность

теперь - тот же аналог для дин.массива


procedure DynArraySetLength(var a: Pointer; typeInfo: PDynArrayTypeInfo; dimCnt: Longint; lengthVec: PLongint);
var
i: Integer;
newLength, oldLength, minLength: Longint;
elSize: Longint;
neededSize: Longint;
p, pp: Pointer;
begin
p := a;

// Fetch the new length of the array in this dimension, and the old length
newLength := PLongint(lengthVec)^;
if newLength <= 0 then
begin
if newLength < 0 then
Error(reRangeError);
DynArrayClear(a, typeInfo);
exit;
end;

oldLength := 0;
if p <> nil then
begin
Dec(PLongint(p));
oldLength := PLongint(p)^;
Dec(PLongint(p));
end;

// Calculate the needed size of the heap object
Inc(PChar(typeInfo), Length(typeInfo.name));
elSize := typeInfo.elSize;
if typeInfo.elType <> nil then
typeInfo := typeInfo.elType^
else
typeInfo := nil;
neededSize := newLength*elSize;
if neededSize div newLength <> elSize then
Error(reRangeError);
Inc(neededSize, Sizeof(Longint)*2);

// If the heap object isn"t shared (ref count = 1), just resize it. Otherwise, we make a copy
if (p = nil) or (PLongint(p)^ = 1) then
begin
pp := p;
if (newLength < oldLength) and (typeInfo <> nil) then
FinalizeArray(PChar(p) + Sizeof(Longint)*2 + newLength*elSize, typeInfo, oldLength - newLength);
ReallocMem(pp, neededSize);
p := pp;
end
else
begin
Dec(PLongint(p)^);
GetMem(p, neededSize);
minLength := oldLength;
if minLength > newLength then
minLength := newLength;
if typeInfo <> nil then
begin
FillChar((PChar(p) + Sizeof(Longint)*2)^, minLength*elSize, 0);
CopyArray(PChar(p) + Sizeof(Longint)*2, a, typeInfo, minLength)
end
else
Move(PChar(a)^, (PChar(p) + Sizeof(Longint)*2)^, minLength*elSize);
end;

// The heap object will now have a ref count of 1 and the new length
PLongint(p)^ := 1;
Inc(PLongint(p));
PLongint(p)^ := newLength;
Inc(PLongint(p));

// Set the new memory to all zero bits
FillChar((PChar(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0);

// Take care of the inner dimensions, if any
if dimCnt > 1 then
begin
Inc(lengthVec);
Dec(dimCnt);
for i := 0 to newLength-1 do
DynArraySetLength(PPointerArray(p)[i], typeInfo, dimCnt, lengthVec);
end;
a := p;
end;


черт те что и сбоку бантик здесь понаворочено !!
да еще и CopyArray(), который мне, к примеру, сто лет в обед не нужен, как правило ... а Борланд мне его навязывает !! мол, хошь не хошь, а я preserve на всяк случай выполню, мол, а ну как ты забыл об этом, дружище-чайник ?!


 
kull   (2003-11-18 15:56) [14]

А кто мешает использовать MoveMemory или CopyMemory?


 
kull   (2003-11-18 16:06) [15]

Да выделение памяти для динамического массива по времени дольше чем reallocmem, но это смотря для какой задачи. Не любить динамические массивы... Ну если нравится следить за распределением памяти, то пожалуйста. Это все равно что нелюбить такую фичу как интерфейсы. Тоже можно по коду try...finally раскидать для обязательного уничтожения объектов.


 
Digitman   (2003-11-18 16:12) [16]


> кто мешает использовать MoveMemory или CopyMemory?


кому ? мне ? мне наоборот эта хрень не нужна, если она мне по моей логике в принципе не нужна) ... а Борланд мне в ответ - нет уж, изволь получить все по полной программе ! Оплачено, мол !!


> Ну если нравится следить за распределением памяти


а ты видел хоть раз, чтобы я задавал вопрос а-ля "куды моя память делась" ?)


 
Digitman   (2003-11-18 16:16) [17]

мил мой ! на то действительно есть try..finally/except, которое следует взять за НЕ-У-КОС-НИ-ТЕЛЬ-НО-Е правило при малейших сомнениях в корректности борландовского (и собственного) кода на предмет мемликов !

тот кто их пользует с умом, тот избавлен от головной боли по поводу утечек)))


 
kull   (2003-11-18 16:32) [18]

var
myobject: TMyObject;
myinterface: IMyInterface;
begin
//одна строка кода
myinterface := TMyObject.Create;
...

//5 строк
myobject := TMyObject.Create;
try
...
fynally
myobject.Free;
end;
end;


 
Digitman   (2003-11-18 16:43) [19]

именно)

плюс - еще туева хуча строчек НЕ-НУЖ-НО-ГО, как правило, кода, которую всандалит Борланд, если ты реализуешь где-то в недрах своего TMyObject использование дин.массивов)) ... ибо везде где это необходимо в коде, касаемом внутренностей TMyObject в части работы с менеджером памяти, ты вполне в состоянии "ручками" поставить эти самые try..finally явно, а не маясь дурью с крайне избыточным кодом и столь же крайне избыточной функц-ю дин.массивов... из-за лени написать лишний раз эти try..finally))



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

Форум: "Основная";
Текущий архив: 2003.11.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.016 c
8-90001
Trekk
2003-07-28 14:24
2003.11.27
Как сделать слои?


6-90038
Sesh
2003-09-30 22:02
2003.11.27
Delphi+Internet


14-90134
alexpiv
2003-11-06 08:57
2003.11.27
Дайте совет!!


1-89984
adif
2003-11-17 14:10
2003.11.27
Как узнать занятость файла приложением?


11-89798
Bartov
2003-03-19 10:52
2003.11.27
Как в KOL организовать AllocateHWnd и DeallocateHWnd?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский