我再一个调用线程的程序中有一个FOR循环。我发现这个FOR循环的的循环变量I从大到小赋值,可是我明明是从0到127,为什么I第一次却是128?原程序见下:
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure threaddone(sender:tobject);
  public
    { Public declarations }
  end;
  tmythread=class(tthread)
  protected
    procedure execute;override;
  end;
var
  Form1: TForm1;
implementation
const
    maxsize=127;
var
  doneflags: integer=0;
  globalarray:array[0..127] of integer;
  nextnumber:integer=0;
  cs:trtlcriticalsection;
{$R *.dfm}function getnextnumber:integer;
begin
    inc(nextnumber);
    result:=nextnumber;
end;
procedure tmythread.execute;
var
    i:integer;
begin
    onterminate:=form1.threaddone;
    entercriticalsection(cs);
    //
    for i:=0 to maxsize do
    begin
        globalarray[i]:=getnextnumber;  //1..128
        sleep(5);
    end;    //
    leavecriticalsection(cs);
end;
procedure tform1.threaddone(sender:tobject);
var
    i:integer;
begin
    inc(doneflags);
    for i:=0 to maxsize do
    begin
     //   if i=0 then showmessage(inttostr(i));
        listbox1.items.Append(inttostr(globalarray[i]));
        //为什么i从128开始呢????
    end;
    if doneflags=2 then
        deletecriticalsection(cs);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
    initializecriticalsection(cs);
    tmythread.Create(false);
    tmythread.Create(false);
end;end.

解决方案 »

  1.   

    For i:=0 to maxsize-1 do
    Bebin
    ......
    end;
    试一试
      

  2.   

    直接
    for i:= 0 to 127试试
      

  3.   

    是不是函数getnextnumber已经把它加到最大值了啊,你不用这个函数试试,直接++好了
      

  4.   

    procedure tform1.threaddone新定义一个别的变量替换i行不行啊?
      

  5.   

    真是邪们了!你用Watch监视i到底是怎么变换的,应该不可能出这样的问题的...
      

  6.   

    同意crossbow(【带三尺剑立不世之功】)
      

  7.   

    Delphi 在编译时使用指令优化, 循环时直接使用计数寄存器操作, 即是逐个减 1, 同时数组的基地址先加上 Sizeof(v) * (Count - 1), 这样保存操作不会有问题. 但有时也会出问题, 这是 Delphi 编译器中存在的 bug.for i := 0 to 127 do
       a[i] := 15;lea eax, a
    add eax, 4 * 127
    mov ecx, 128
    @loop1:
    mov [eax], 15;
    dec eax, 4
    loop @loop1
      

  8.   

    老兄,你写错了!procedure TForm1.Button1Click(Sender: TObject);
    begin
        initializecriticalsection(cs);
        tmythread.Create(false);
        // tmythread.Create(false); // 重复了
    end;
      

  9.   

    //   if i=0 then showmessage(inttostr(i));
            listbox1.items.Append(inttostr(globalarray[i]));
            //为什么i从128开始呢????我想问题是这儿:globalarray[i]试试 加一个变量  ii : integer;然后改程序为     //   if i=0 then showmessage(inttostr(i));
              ii:=i; 
              listbox1.items.Append(inttostr(globalarray[ii]));
            //为什么i从128开始呢????
      

  10.   

    找到原因,
    procedure tform1.threaddone(sender:tobject);
    var
        i:integer;
    begin
        inc(doneflags);
        entercriticalsection(cs); // 这样才能确保显示 129..256(128 项),
    // 否则显示的是两个线程的混合并且是混排的结果(256项),显示结果数据的顺序取决于 CPU 时间,在此例中,线程中每赋一个值,休息 5 毫秒,因此 ListBox 中显示的第一项是线程2 产生的值(因为线程2 早等在那儿了),后面显示线程1产生的 127 个值(5毫秒足够了),再显示线程2 产生的 128 个值。
        for i:=0 to maxsize do
        begin
           listbox1.items.Append(inttostr(globalarray[i]));
        end;
        leavecriticalsection(cs);
        if doneflags=2 then
            deletecriticalsection(cs);
    end;至于你看到的 i 值为 128,这可能是 IDE 的 BUG 了,它的真实内容还是 0。
      

  11.   

    hiflower(花) :
    我找到了原因,只要把SLEEP(5)去掉就可以了,
    但是我不明白,SLEEP这句,是在数组赋值的时候执行的吧?我跟踪调式发现,数组的值在第一个循环结束后是1128,正确的。
    为什么在给LISTBOX1添加值时,开始I=128呢,数组范围是0。。127,为什么不报告边界错误呢,