hi, i have a small problem. ...
here :
When i run my program, i'am seing this message :Code:unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); procedure destroy(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.destroy(Sender: TObject); var i: integer; a:array[1..10] of integer; begin for i:=1 to 10 do a[i]:=0; end; procedure TForm1.Button1Click(Sender: TObject); var max,i,j,n,gr:integer; s:string; a:array[1..10] of integer; begin for i:=0 to 10 do begin s:=Memo1.Lines[i]; val(s,n,gr); j:=j+1; If gr=0 then a[j]:=StrToInt(Memo1.Lines[i]); end; for i:=1 to 10 do if a[i]>max then max:=a[i]; Edit1.Text:=IntToStr(max); end; end.
help ?
thanks
Does the error message happen immediately, or after you press the button?
When i pressed the button.
j should really be initialized before using it, but it looks like it varies from 1 to 11, which will mean it's an invalid index in array a. Thus, the access violation.
Delphi has a really good debugger. It's worthwhile to set a breakpoint on the first line of your method and trace through it to see what line is causing the error.
i edited
begin
for i:=0 to 10 do
a[i]:=0;
end;
TO
begin
for i:=1 to 10 do
a[i]:=0;
end;
but when i compiled, i sow this message :
next, i presed OK and i sow this :
help ?
I'm pretty sure your error is on this line:
Also, do you ever initialize the value of j?Code:a[j]:=StrToInt(Memo1.Lines[i]);
You may want to try this:
This will give you a debugging message and help you determine where the error is occurring and why.Code:procedure TForm1.Button1Click(Sender: TObject); var max,i,j,n,gr:integer; s:string; a:array[1..10] of integer; begin for i:=0 to 10 do begin s:=Memo1.Lines[i]; val(s,n,gr); j:=j+1; showmessage('i: '+inttostr(i)+', s: '+inttostr(s)+', gr: '+inttostr(gr)+', j: '+inttostr(j)); If gr=0 then a[j]:=StrToInt(Memo1.Lines[i]); end; for i:=1 to 10 do if a[i]>max then max:=a[i]; Edit1.Text:=IntToStr(max); end;
Last edited by WingedPanther; 12-22-2009 at 02:18 PM.
Sorry, remove the one around s.
Sorry, but this is just silly.
First off, the code in your "destroy" method does absolutely nothing. Secondly, your array a only contains 10 items, numbered 1 through 10, and you're COUNTING from 0 to 10. So no matter what you set j to, you're trying to fill more array elements than you have. Thus error.
Try:
Now, this will work. Note that setting array values in a destructor is useless.Code:unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); //procedure destroy(Sender: TObject); REMOVE THIS //PLUS, if you're going to make a destroy, do THIS: //destructor Destroy; override; //destructor, not procedure. And override it. Call "inherited;" last in your destructor private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { remove all this procedure TForm1.destroy(Sender: TObject); var i: integer; a:array[1..10] of integer; begin for i:=1 to 10 do a[i]:=0; end; } procedure TForm1.Button1Click(Sender: TObject); const linecount=11 highestlinenum=linecount-1; var max,i:integer; s:string; a:array[0..highestlinenum] of integer; //note that I put a ZERO begin for i:=0 to highestlinenum do a[i]:=StrToIntDef(Memo1.Lines[i],0); //please be advised you need 11 lines in the memo! Numbered from 0 to 10!! { begin s:=Memo1.Lines[i]; val(s,n,gr); If gr=0 then a[j]:=StrToInt(Memo1.Lines[i]); ===>else what??? a[j] is what??? a is not initialized (it's LOCAL, so if it's not ===>initialized here, it won't be initialized at all end; } max:=a[0]; //initialize your max value, or it might start out //with 13678736834 (random number) for i:=1 to highestlinenumdo if a[i]>max then max:=a[i]; Edit1.Text:=IntToStr(max); end; end.
After all, the array is about to be destroyed anyway. And if you want to keep
data across method calls (object procedure/function calls), you have to create
FIELDS in the object, like so:
This is just a simple example. Try the help files for more info on how to program.Code:type TObj=class FNumbers:array[0..9] of integer; FTotal:integer; constructor Create; destructor Destroy; override; procedure Init; procedure Calc; procedure Show; //when making a form's CREATE and DESTROY, use the form's //OnFormCreate and OnFormDestroy events! end; constructor TObj.Create; var n:integer; begin for n:=0 to high(FNumbers) {this is 10} do FNumbers[n]:=n; FTotal:=0; //you never have to init to 0 for fields ShowMessage('I have been created!!'); end; destructor TObj.Destroy; override; begin //there's nothing to free. Tell the world I'm dying. ShowMessage('Bye bye'); inherited; //this calls the "destroy" from TObject, the parent type of this class end; //now the object is freed (after end) procedure TObj.Init; var n:integer; begin for n:=0 to High(FNumbers) do FNumbers[n]:=10+n*5; //this does nothing interesting, but "init" is different from "create" //again, for no particular reason FTotal:=0; //this is set to 0, in case someone reads it before calling something else. end; procedure Tobj.Calc; var n:integer; begin FTotal:=0; //don't forget this... :S For instance, if you call "calc" twice in a row... for n:=0 to high(FNumbers) do Inc(FTotal,FNumbers[n]); //look up "inc" in the help end; procedure UseSillyObject; var o1,o2:TObj; begin o1:=TObj.Create; o2:=TObj.Create; o1.Init; ShowMessage('o1 before:'+IntToStr(o1.FTotal)); o1.Calc; ShowMessage('o1 after:'+IntToStr(o1.FTotal)); o2.Calc; ShowMessage('o2 after calc (no init):'+IntToStr(o2.FTotal)); o1.Free; //you don't have to create or free forms, but your own objects, you do. o2.Free; end;
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks