-2

This issue appears only with numbers, bigger, then 12 including.

Those two pictures captured in one time. How it is even possible?

For loop must go from 0 to 12-1=11, doesn't it?

Nevertheless, when I use while loop instead, it works fine.

Is it my fault or Delphi's?

P.S. Code down bellow. 1 1

unit Unit1;
interface

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

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    Label1: TLabel;
    Button3: TButton;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure StringGrid1KeyPress(Sender: TObject; var Key: Char);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  n:Integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);    //Button, that sets array length
var
  i, index:Integer;
begin
    val(Edit1.Text, n, index);                  
    if(index<>0) then
    begin
      ShowMessage('Wrong number');
      Edit1.Clear();
      exit;
    end;
    StringGrid1.ColCount:=n;
    for i:=0 to n-1 do                           
      StringGrid1.Cells[i,0]:=IntToStr(i+1);
    StringGrid1.SetFocus();
end;

procedure TForm1.Button2Click(Sender: TObject);        //Main button
var
  i, index:Integer;
  a:array[0..10] of Real;
  denom, sum:Real;
begin
  i:=0;
  sum:=0;
  denom:=-1;

 //that for loop from screenshot is here

  for i:=0 to n-1 do
  //while i<=(n-1) do
  begin
    Val(StringGrid1.cells[i,1], a[i], index);    
    if(index<>0) then
    begin
      ShowMessage('Wrong number with ' + IntToStr(i+1) + ' Id');
      StringGrid1.Col:=i;
      StringGrid1.Row:=1;
      StringGrid1.SetFocus();
      exit;
    end;
    a[i]:=a[i]/denom;                            
    sum:=sum+a[i];
    StringGrid1.Cells[i,2]:=FloatToStrF(a[i],ffFixed,5,3);    
    denom:=-denom*(i+2);
    //Inc(i);
    end;
    Label2.Caption:=FloatToStrF(sum,ffFixed,5,3);
end;

//code down bellow just allow to go to another cell by pressing Enter


procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
begin
  if  (Key=#13) and (StringGrid1.Col=(n-1)) then   
      Button2.SetFocus()
  else if (Key=#13) and (StringGrid1.Col<>(n-1)) then
      StringGrid1.Col:=StringGrid1.Col+1;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Close();
end;

end.
Kamerton
  • 75
  • 7
  • 3
    [Look here](https://stackoverflow.com/a/35478474/2292722) for an explanation of how the *loop control variable* is used in various situations. – Tom Brunberg Oct 08 '17 at 14:43
  • A loop with an exit statement in it ? I dont even have to read your code to know their is faulty logic here. If you loop has to stop on a condition, than use a conditional loop (repeat until or while do) and not an uncondition loop. Also all code after your loop is not executed when the exit is fired. This is very unreadable code – GuidoG Oct 09 '17 at 10:55

2 Answers2

-1

As to answer your question of 'how is this even possible'...

In your screen, n is 12. As pointed out by Kermation, the highest index of a is 10, so when i is 11, unless you have range checking activated, when you write to a[11] (i=11) you will overwrite something else. This is in the local variable area so it might be i, for instance, or even internal variables you can't see like the limit used for the for loop, which is calculated at the start of the loop. Once you allow this to happen, pretty much anything is possible.

Of course the exact manifestation of the problem will very from one version of the compiler to another. In one version you might get away with it. in another you won't.

Dsm
  • 5,870
  • 20
  • 24
-2

Array a size was smaller, then amount of cells.

Kamerton
  • 75
  • 7