ポインターについて??


ペコ  2003-10-31 22:49:28  No: 5533

以下のようなプログラムを書きました。
 private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;
  Xs,Ys: PDArray;  // pointer to array of double;
  Ns: integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i,NDiv:integer;
XDiv: double;
Q1:double;
H1:double;
begin
   Case ComboBox1.ItemIndex of            //  補間法を設定
     0: Interpolate1.Method:=Linear;
     1: Interpolate1.Method:=Square;
     2: Interpolate1.Method:=CSpline;
   end;
   Interpolate1.DKnot( Ns, Xs, Ys );     //  節点を指定して補間パラメータを計算する  
   NDiv:=StrToInt(Edit1.Text);
   XDiv:=(Xs[Ns]-Xs[1])/NDiv;
for i:=0 to   NDiv do
 begin
     Q1:=XDiv*i;
     H1:=Interpolate1.Value(Q1) ; //与えられたX値に対する補間値を計算する
     Chart1.Series[1].AddXY(Q1,H1);
   end;
 end;

procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
   Ns:=6;   // 節点の個数
   GetMem( Xs, Ns*8);
   GetMem( Ys, Ns*8);
 For i:=0 to  Ns do
  begin
   Xs[i]:=i;
   Ys[i]:=(-3.6*Power(Xs[i],3))+(0.000102*Power(Xs[i],2))+(0.00187*Xs[i])+3.7;
  end;
end;

procedure TForm1.Interpolate1FPError(Sender: TObject);
begin
 Application.MessageBox( PChar(Interpolate1.ErrorMessage), 'FP Error Message', mb_OK + mb_DefButton1);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 FreeMem( Xs, Ns*8 );
 FreeMem( Ys ,Ns*8 );
end;

end.

実行させると、思うようにプログラムはうごくのですが
プログラムを終了させようとすると
EInvalid Pointer ,クラスの例外が生成しました。
’無効なポインター操作’と
デバッカ例外が発生してしまいます。
FormCloseのところのプログラムがおかしいのでしょうか?

よろしくお願いします。


にしの  2003-10-31 23:07:30  No: 5534

> GetMem( Xs, Ns*8);
> GetMem( Ys, Ns*8);
Xs := SysGetMem(Ns*8);
Ys := SysGetMem(Ns*8);

> FreeMem( Xs, Ns*8 );
> FreeMem( Ys ,Ns*8 );
SysFreeMem( Xs );
SysFreeMem( Ys );

でどうでしょう。


masayan  2003-10-31 23:37:24  No: 5535

Form1のOnCreateのループですが
>For i:=0 to  Ns do
→Xs,Ysそれぞれ[0]〜[6](7個の要素)を初期化してますよ。

For i := 0 to Ns - 1 do
ではないでしょうか?

他にも添え字の範囲を超えている可能性はないですよね?


ペコ  2003-11-01 00:19:02  No: 5536

にしのさんmasayanさんありがとうございます
> GetMem( Xs, Ns*8);
> GetMem( Ys, Ns*8);
Xs := SysGetMem(Ns*8);
Ys := SysGetMem(Ns*8);

> FreeMem( Xs, Ns*8 );
> FreeMem( Ys ,Ns*8 );
SysFreeMem( Xs );
SysFreeMem( Ys );

としてみたのですがやはりエラーが表示されてしまいます。


にしの  2003-11-01 00:27:11  No: 5537

別なところが原因のような気がします。
XsとYsは、SysGetMemした後SysFreeMemするまで変更されていませんよね。
こちらでは、FormCreate, FormCloseのみ用意してテストしました。
まずは、新規プロジェクトにて、上に示されたFormCreate, FormCloseで試してみてください。
うまく動作しませんか?
もし新規プロジェクトで正しく動作しているのであれば、何か他の処理の中に問題があるのだと思います。

うまく動かない場合は、開発環境(バージョンなど)も書いてください。こちらでの環境は、Delphi7Proです。


masayan  2003-11-01 00:57:08  No: 5538

Button1Clickの
>   Interpolate1.DKnot( Ns, Xs, Ys );     //  節点を指定して補間パラ
が怪しいような...

とりあえず...
  procedure TForm1.Button1Click(Sender: TObject);
  var
    i,NDiv:integer;
    XDiv: double;
    Q1:double;
    H1:double;
    Xs2,Ys2 : PDArray; // <= これを追加
  begin
    :
    <中略>
    :

    Xs2 := Xs;
    Ys2 := Ys;
    Interpolate1.DKnot( Ns, Xs2, Ys2 );  // 引数をXs2,Ys2に変更  

としてみてはどうでしょう?


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

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






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