動的なメモリの確保をするには

解決


やすか  2006-06-01 03:20:47  No: 21957

質問です。

type
  xxx=Rrcord
    aaa:String;
    bbb:String;
end;
type
  yyy=Rrcord
    ccc:String;
    ddd:String;
end;

data1:array of xxx;
data2:array of yyy;

data1.aaa(可変長、カンマ区切のデータ)をdata2の構造体にセットしたいです。

data1.aaaには、'11111,22'の繰り返し何件かわからない...

setLength(data2,Length(data1[0].aaa));

この構造体にデータをセットしたいのですが、件数が動的で
メモリの確保をどのようにしたらいいのかわかりません。
よろしくお願いいたします。


AL  2006-06-01 04:16:58  No: 21958

data1[0].aaaのデータをdata2のどこに入れるのが不明ですが、
こんな感じにしてはいけないんでしょうか?

StringList := TStringList.Create;
StringList.CommaText := data[0].aaa;

SetLength(data2, StringList.Count);

for i = 0 to StringList.Count - 1 do
  data2[0].ccc? := StringList.Strings[i]; 
  // 左辺が不明なので読み替えてください。

StringList.Free;


ママん  2006-06-01 05:11:23  No: 21959

TListッスよTList!

unit Unit1;

interface

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

type
  PDataA = ^TDataA;
  TDataA = Record
    aaa:String;
    bbb:String;
end;
type
  PDataB = ^TDataB;
  TDataB = Record
    ccc:String;
    ddd:String;
end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private 宣言 }
    myList:TList;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  aData:PDataA;
  i:Integer;
begin
  new(aData);
  for i:=0 to 100 do
  begin
    aData.aaa := inttostr(GetTickCount);
    aData.bbb :=inttostr(i) + '-' + inttostr(GetTickCount);
    myList.Add(aData);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
myList:=TList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
myList.Clear;
myList.Free;
end;

end.


えーと  2006-06-01 05:17:43  No: 21960

> myList.Clear;

その前に、すべての項目について Dispose(PDataA(myList[i])) しないとリークします。


ママん  2006-06-01 06:03:00  No: 21961

あぁ…適当すぎる…
えーとさん指摘ありがとうございます。
newの位置も間違ってます。

procedure TForm1.Button1Click(Sender: TObject);
var
  aData:PDataA;
  i:Integer;
begin
  for i:=0 to 100 do
  begin
    new(aData);
    aData.aaa :=inttostr(GetTickCount);
    aData.bbb :=inttostr(i) + '-' + inttostr(GetTickCount);
    myList.Add(aData);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  aData:PDataA;
  i:Integer;
begin
  for i:=myList.Count-1 downto 0 do
  begin
    aData:=PDataA(myList.Items[i]);
    Dispose(aData);
  end;
  myList.Clear;
end;


んー  2006-06-01 21:27:58  No: 21962

ママんさんも古くからのDelphi使いっぽいですね。
私もpointerでいいような気もしますが
クラスするのも、アリなのではないかと
思いますので、紹介します。

PDataAに相当する TObjectを継承したクラスを作成

TDataA = class
  aaa: string;
  bbb: string;
end;

TListEx = class(TList)
  function GetItems(index: integer): TDataA;
  function Add: TDataA;
  property Items[index: integer]: TDataA read GetITems;
end;

クラスなので
TDataA = class
  aaa: TStringList;
  bbb: string;
  constructor Create; 
end;
のようにしてコンストラクタで初期化もできます
constructor TDataA.Create;
begin
  aaa:= TStringList.Create;
end;

こんなことも。
FList: TListEx;

var
  a: TDataA;
begin
  a:= FList.Add;
  a.aaa.CommaText:='aaa,bbb,ccc';
  writeln( a.aaa[0]);
end;

TPersistentあたりも調べてみるといいかも。


やすか  2006-06-10 03:52:47  No: 21963

今、出張から帰ってきました。

ありがとうございました。

大変、参考になりました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加