Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как работать с динамическими записями. [Win95/98]


Страницы:   1 2

MegaVolt ©   (2002-07-11 16:49:00) 

В ниже приведённом примере я пытался создать пример для работы с динамическими записями но возникли некоторые проблемы при попытке удаления второго списка т.к. при его создании я не копировал реальные данные а скопировал только указатели на них и когда я удалил первый список то все данные перестали существовать но во втором списке на них остались указатели.
Вопросы:
Как правильно копировать именно данные между:
1. PData и PData
2. PData и TData
3. TData и PData
4. TData и TData
Заранее благодарен :)


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TsData=record
List:TList;
Str:string;
end;

TData=packed record
Test: Int64;
Attributes: DWORD;
Name: String;
end;

PData= ^TData;

var
Form1: TForm1;
MyList1,MyList2:TsData;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
MyList1.List:=TList.Create;
MyList2.List:=TList.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
z:PData;
begin
//Создаём динамический массив:
For i:=1 to 1000000 do
begin
New(z);
z^.Attributes:=123456;
z^.Test:=98765432;
z^.Name:="Help me";
MyList1.List.Add(z);
end;
ShowMessage("Ok");
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
z:PData;
begin
//Копируем из первого списка во второй;
For i:=1 to 1000000 do
begin
z:=MyList1.List[i-1];
MyList2.List.Add(z);
end;
ShowMessage("Ok");
end;

procedure TForm1.Button3Click(Sender: TObject);
var
z:PData;
begin
//удаляем оба массмва:
while MyList1.List.Count<>0 do
begin
z:=MyList1.List[MyList1.List.count-1];
Dispose(z);
MyList1.List.Delete(MyList1.List.Count-1);
end;
while MyList2.List.Count<>0 do
begin
z:=MyList2.List[MyList2.List.count-1];
Dispose(z);
MyList2.List.Delete(MyList2.List.Count-1);
end;
ShowMessage("Ok");
end;

end.


valery_f   (2002-07-11 17:30:00) [21]

> MegaVolt © (11.07.02 17:06) ...Я в данном примере не правильно копирую...

Точно... Во-первых, нужно создать новую запись и копировать в нее (а не копировать указатель). А во-вторых, когда бежишь по готовому списку, то лучше идти от нуля до Count-1, а не полагаться на константы (это так, правило хорошего тона :) В общем:

procedure TForm1.Button2Click(Sender: TObject);
var i:integer; z:PData;
begin
//Копируем из первого списка во второй;
For i:=0 to MyList1.Count-1 do begin
New(z);
z^ := PData(MyList1.List[i])^;
MyList2.List.Add(z);
end;
ShowMessage("Ok");
end;

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

for i := 0 to MyList1.List.Count-1 do begin
z:=MyList1.List[i];
Dispose(z);
end;
MyList1.Clear;

или, если удаляешь не все элементы:

for i := 0 to MyList1.List.Count-1 do begin
z:=MyList1.List[i];
if надо then begin
Dispose(z);
MyList1.List[i] := nil;
end;
end;
MyList1.Pack;


MegaVolt   (2002-07-11 17:27:00) [22]

Спасибо приогромное :):):):):)


Digitman   (2002-07-11 17:19:00) [23]

procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
src, dst :PData;
begin
//Копируем из первого списка во второй;
For i:=1 to 1000000 do
begin
src:=MyList1.List[i-1];
New(dst);
dst^ := src^;
MyList2.List.Add(dst);
end;
ShowMessage("Ok");
end;


MegaVolt   (2002-07-11 17:18:00) [24]

Так на примере нельзя написать ведь похоже всего одна строчка пли-из :)


Skier   (2002-07-11 17:12:00) [25]

>MegaVolt

> У меня при копировании копируется только указатель а нужно
> чтобы данные


Нужно использовать разадресацию (^) чтобы копировать данные.


Skier   (2002-07-11 17:10:00) [26]

>MegaVolt


MegaVolt   (2002-07-11 17:06:00) [27]

Так удаляю я правильно т.к. я считаю что это отдельные данные. Я в данном примере не правильно копирую :( Вот я и спрашиваю как правильно скопировать а не удалять. У меня при копировании копируется только указатель а нужно чтобы данные. Пример лишон практического смысла кроме демонстрации :)


Digitman   (2002-07-11 17:02:00) [28]

procedure TForm1.Button3Click(Sender: TObject);
var
z:PData;
begin
//удаляем оба массмва:
while MyList1.List.Count<>0 do
begin
z:=MyList1.List[MyList1.List.count-1];
Dispose(z);
MyList1.List.Delete(MyList1.List.Count-1);
end;
while MyList2.List.Count<>0 do
begin
z:=MyList2.List[MyList2.List.count-1];
// Dispose(z); // !!!! зачем ??? записи уже уничтожены
MyList2.List.Delete(MyList2.List.Count-1);
end;
ShowMessage("Ok");
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо