Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 26170
Рейтинг: 2127
#1: 2007-11-03 14:08:32 ЛС | профиль | цитата
Ну вот я и добил набор компонентов для работы с массивами MT-потоков. Набор состоит из трех основных компонентов -- MT_MTArray, MT_MTArrayRW и MT_MTArrayEnum

------------ Дoбавленo:


Galkov, что скажешь по этим компонентам? Да и по остальным (MT_AddData и MT_Stack). Хочу знать твое мнение.

-- Удалено с выходом пакета для работы с MT-потоками --
карма: 22

0
Ответов: 9906
Рейтинг: 351
#2: 2007-11-03 15:03:39 ЛС | профиль | цитата
Мое мнение таково, что прием "вертикальных" данных в "горизонтальный" поток (через _Get) без копирования - приведет к проблемам
Ровно к таким же, как в топике с накоплением MT-данных, где тв первый раз спрашивал про MT

Скажем, читаешь элемент массива, первой точной хаба меняешь данные в этом месте массива, второй точкой используешь ранее прочитанное

карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#3: 2007-11-03 16:38:21 ЛС | профиль | цитата
Galkov, я очень хорошо усвоил эту проблему, и не раз на нее натыкался, но мне показалось, что я от этого избавился при возвращении данных вот в этом месте


function ThiMT_MTArray._Get;
var dt:PData;
ind:integer;
begin
ind := ToIntIndex(Item);
if(ind >= 0)and(ind < _Count)then begin
Result := true;
dt := PData(FList.Items[FList.Count-1]);
CopyData(@Val, dt);
end
else Result := false;
end;
В данном месте я делаю копию данных.
карма: 22

0
Ответов: 9906
Рейтинг: 351
#4: 2007-11-03 18:08:48 ЛС | профиль | цитата
Ну может и не досмотрел....
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#5: 2007-11-03 18:21:10 ЛС | профиль | цитата
Galkov, всеравно, спасибо.
карма: 22

0
Ответов: 9906
Рейтинг: 351
#6: 2007-11-03 20:02:50 ЛС | профиль | цитата
nesco писал(а):
В данном месте я делаю копию данных

Отсюда вытекает вопрос: а в каком месте ты уничтожаешь эту копию




#pas
...
dt := ReadMTData(_Data,_data_Value);
CopyData(@dt,@dt);
Arr._Set(ind,dt);
FreeData(@dt);
...
Зачем
Разве _Set не занимается копированием
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#7: 2007-11-03 21:11:16 ЛС | профиль | цитата
Galkov писал(а):
Отсюда вытекает вопрос: а в каком месте ты уничтожаешь эту копию
Да, действительно, нигде, добавлю.
Galkov писал(а):
Разве _Set не занимается копированием
Занимается, лишний раз перестраховался, сейчас уберу лишнее копирование в _Set и _Add.

карма: 22

0
Ответов: 9906
Рейтинг: 351
#8: 2007-11-03 21:36:22 ЛС | профиль | цитата
nesco писал(а):
лишний раз перестраховался, сейчас уберу

Только не забудь в _Set поменять местами уничтожение и копирование
------------ Дoбавленo:

Хотя зря я это наверное, если данные на улицу только в виде копий попадают.......
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#9: 2007-11-03 21:42:09 ЛС | профиль | цитата
Galkov писал(а):
Отсюда вытекает вопрос: а в каком месте ты уничтожаешь эту копию
Посмотрел внимательно, копию удалять нельзя, она попадает в FItem и может попасть в нижнюю точку Item.
Galkov писал(а):
Разве _Set не занимается копированием
Попробовал, тут же получил фигу (RunTime Error).
карма: 22

0
Ответов: 9906
Рейтинг: 351
#10: 2007-11-03 21:45:21 ЛС | профиль | цитата
nesco писал(а):
копию удалять нельзя,
Не удалять - тоже нельзя

nesco писал(а):
Попробовал, тут же получил фигу
Не аргумент
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#11: 2007-11-03 21:54:49 ЛС | профиль | цитата
Хотел подробнее разобрать _Set


procedure ThiMT_MTArray._Set;
var ind:integer;
dt:PData;
begin
ind := ToIntIndex(Item);
if(ind >= 0)and(ind < _Count)then begin
dt := PData(FList.Items[ind]);
FreeData(dt);
dispose(dt);
new(dt);
CopyData(dt,@Val);
FList.Items[ind]:= dt;
end;
end;
Тут я уничтожаю предыдущий сохраненный МТ-поток, оформляю новыое место и копирую туда данные. dt очищать нельзя -- это хранилище, а Val -- это внешние данные, лучше не трогать.
------------ Дoбавленo:

Про _Get тоже интересно


function ThiMT_MTArray._Get;
var dt:PData;
ind:integer;
begin
ind := ToIntIndex(Item);
if(ind >= 0)and(ind < _Count)then begin
Result := true;
dt := PData(FList.Items[FList.Count-1]);
CopyData(@Val, dt);
end
else Result := false;
end;
dt -- хранилище, оно очишается по выходу, FreeData(dt) приведет к очистке содержимого. Val попадет дальше на FItem в RW-компоненте.
Galkov писал(а):
Не аргумент

Я понимаю, уточню -- тупое убирание Copy(@dt,@dt) приводит к краху.
карма: 22

0
Ответов: 9906
Рейтинг: 351
#12: 2007-11-03 22:11:42 ЛС | профиль | цитата
nesco писал(а):
dt очищать нельзя -- это хранилище
Мда...
А я всегда думал, что очищать нельзя, потому что не создавал...

nesco писал(а):
dt -- хранилище, оно очишается по выходу
Чего-чего

nesco писал(а):
уточню -- тупое убирание Copy(@dt,@dt) приводит к краху
Прошу большого пардона, но мне неизвестен такой способ программирования: "тупое убирание"
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#13: 2007-11-03 22:21:02 ЛС | профиль | цитата
Galkov писал(а):
Чего-чего

Поторопился выразиться -- указатель на область данных. Если я применяю к нему FreeData(dt), то данные очищаются, я пробовал, и, действительно, данные пропали.
Вот тут я пытался сделать так


procedure ThiMT_MTArrayRW._work_doWrite;
var Arr:PArray;
Ind:TData;
dt:TData;
begin
Arr := ReadArray(_data_Array);
if Arr=nil then exit;
Ind := ReadData(_Data,_data_Index,@_prop_Index);
dt := ReadMTData(_Data,_data_Value);
// CopyData(@dt,@dt);
Arr._Set(ind,dt);
FreeData(@dt);
end;
И получил крэш.
Galkov писал(а):
Мда...
А я всегда думал, что очищать нельзя, потому что не создавал...
Но как не создавал, а вот тут


procedure ThiMT_MTArray._Add;
var dt:PData;
begin
new(dt);
CopyData(dt,@Val);
FList.Add(dt);
end;
по new(dt) создаем область данных и указатель сохраняем в списке.
карма: 22

0
Ответов: 9906
Рейтинг: 351
#14: 2007-11-03 22:40:47 ЛС | профиль | цитата
nesco писал(а):
Если я применяю к нему FreeData(dt)

"Если" - не интересует.
Интересуют вышеозначенные причины для удаления.
Она может быть одна: я эти данные и создавал.

nesco писал(а):
И получил крэш

Последнее 768-е китайское предупреждение: ДО комментариев вышеозначенная причина для FreeData - БЫЛА.

nesco писал(а):
а вот тут

Писать коды надо так, чтобы не употреблять "а вот тут" про другие методы.
Ты, как автор кодов, не можешь знать, сколько раз будет сделано "а вот тут" и сколько "а вот здесь", и совпадут ли между собой эти количества.
Вывод: "а вот тут" - не говорит вообще ни о чем.
карма: 9

0
Разработчик
Ответов: 26170
Рейтинг: 2127
#15: 2007-11-04 23:30:01 ЛС | профиль | цитата
Galkov писал(а):
Писать коды надо так, чтобы не употреблять "а вот тут" про другие методы.

Но вот не понял я, как я могу применять _Set к данным которыя я не добавил в _Add?
Galkov писал(а):
Последнее 768-е китайское предупреждение: ДО комментариев вышеозначенная причина для FreeData - БЫЛА.

Там, вроде про копию говорили, а не про FreeData.

------------ Дoбавленo:

Galkov, исправил, собственно, сам массив (параллельно нашел тупую ошибку в индексации списка ), выкинул переменные и оставил только работу со списком.

------------ Дoбавленo:

А вот пример для проверки динамической работы MTArray


#sha
Add(MainForm,5669892,224,259)
{
Left=20
Top=105
Width=200
Height=125
Position=1
link(onCreate,6105249:doWork2,[])
}
Add(Button,4235013,224,168)
{
Left=35
Top=10
TabOrder=-1
Caption="Add"
link(onClick,5188173:doFor,[])
}
Add(MT_Add,10600462,343,168)
{
Data=Integer(1)
link(onAdd,5703693:doAdd,[])
link(Data,2582865:Value,[])
}
Add(Memory,2582865,343,119)
{
Default=Integer(1)
}
Add(For,5188173,280,168)
{
End=50000
link(onEvent,10600462:doAdd,[])
link(onStop,8455873:doWork1,[(333,181)])
}
Add(MT_MTArrayRW,5703693,413,154)
{
link(Array,1664879:Array,[])
}
Add(MT_MTArray,1664879,413,70)
{
}
Add(Button,8980875,224,70)
{
Left=35
Top=60
TabOrder=-1
Caption="Clear"
link(onClick,14222601:doEvent1,[])
}
Add(Application,16410378,413,203)
{
}
Add(HubEx,6105249,329,287)
{
link(onEvent,1999727:doWork3,[(389,300)])
}
Add(DoData,12617003,413,252)
{
link(onEventData,6876267:doPart,[])
link(Data,16410378:AppFileName,[])
}
Add(FilePart,6876267,462,252)
{
NameWOExt=1
link(onName,10003327:doFindName,[])
}
Add(EnumProcess,10003327,525,238)
{
DebugPrivilege=0
Point(doFindName)
Point(doGetMemoryInfo)
Point(onGetMemoryInfo)
Point(onFind)
link(onGetMemoryInfo,1479358:doOperation,[])
link(onFind,10003327:doGetMemoryInfo,[(570,258)(570,293)(513,293)(513,272)])
}
Add(Hub,14222601,343,70)
{
link(onEvent1,1664879:doClear,[])
link(onEvent2,1999727:doWork1,[(389,83)])
}
Add(HubEx,1999727,385,245)
{
link(onEvent,12617003:doData,[])
}
Add(Edit,14728435,644,245)
{
Left=105
Top=35
Width=55
TabOrder=-1
Text=""
}
Add(Label,9810967,224,119)
{
Left=110
Top=15
Width=41
Height=17
Caption="Memory"
}
Add(Math,1479358,588,245)
{
OpType=3
Op2=1024
ResultType=0
link(onResult,14728435:doText,[])
}
Add(Button,6551973,224,217)
{
Left=35
Top=35
TabOrder=-1
Caption="Set"
link(onClick,9516121:doFor,[])
}
Add(For,9516121,280,217)
{
End=50000
link(onEvent,5703693:doWrite,[(398,223)(398,167)])
link(onStop,8455873:doWork2,[])
}
Add(HubEx,8455873,329,217)
{
Angle=1
link(onEvent,6105249:doWork1,[])
}


------------ Дoбавленo:


Galkov, что скажешь? Жду, жду ответа, а ты молчишь. Хорошо, если ткнешь пальцем, где чего не так.

------------ Дoбавленo:


Я еще пересмотрел код и добавил в _Set и _Add FreeData

#pas
unit hiMT_MTArray; { Компонент MT_MTArray (массив MT-потоков) ver 1.20 }

interface

uses Kol,Share,Debug;

type
ThiMT_MTArray = class(TDebug)
private
Arr:PArray;
FList:PList;
procedure _Set(var Item:TData; var Val:TData);
function _Get(Var Item:TData; var Val:TData):boolean;
function _Count:integer;
procedure _Add(var Val:TData);
public
constructor Create;
destructor Destroy; override;
procedure _work_doClear(var _Data:TData; Index:word);
procedure _var_Array(var _Data:TData; Index:word);
end;

implementation

constructor ThiMT_MTArray.Create;
begin
inherited;
FList := newlist;
end;

destructor ThiMT_MTArray.Destroy;
var i:integer;
begin
for i := 0 to FList.Count-1 do begin
FreeData(PData(FList.Items[i]));
dispose(PData(FList.Items[i]));
end;
FList.Free;
inherited;
end;

procedure ThiMT_MTArray._Set;
var ind:integer;
begin
ind := ToIntIndex(Item);
if(ind >= 0)and(ind < _Count)then begin
FreeData(PData(FList.Items[ind]));
CopyData(PData(FList.Items[ind]),@Val);
FreeData(@Val);
end;
end;

procedure ThiMT_MTArray._Add;
var dt:PData;
begin
new(dt);
CopyData(dt,@Val);
FreeData(@Val);
FList.Add(dt);
end;

function ThiMT_MTArray._Get;
var ind:integer;
begin
ind := ToIntIndex(Item);
if(ind >= 0)and(ind < _Count)then begin
Result := true;
FreeData(@Val);
dtNull(Val);
CopyData(@Val, PData(FList.Items[ind]));
end
else Result := false;
end;

function ThiMT_MTArray._Count;
begin
Result := FList.Count;
end;

procedure ThiMT_MTArray._var_Array;
begin
if Arr = nil then
Arr := CreateArray(_Set, _Get, _Count, _Add);
dtArray(_Data,Arr);
end;

procedure ThiMT_MTArray._work_doClear;
var i:integer;
begin
for i := 0 to FList.Count-1 do begin
FreeData(PData(FList.Items[i]));
dispose(PData(FList.Items[i]));
end;
FList.Clear;
end;

end.
карма: 22

0
15
Сообщение
...
Прикрепленные файлы
(файлы не залиты)