本帖最后由 huboy 于 2010-12-16 10:18:47 编辑

解决方案 »

  1.   

    如果没办法就只有来最笨的办法了:入队前 转 string .出队后转 Tcomdata..唉,,这又是时间消耗啊。。得不偿失。。
      

  2.   

    看看每次传入的Cmd,是一个新的实例地址,还是一个保持不变的地址啊,var 类型是按地址处理的
      

  3.   

    function InQueue(var Queue: Send_Queue; var Cmd: cmd_Struct) : Boolean; 
    干嘛Cmd也非要加VAR,这不加VAR是传值,加VAR是传址
      

  4.   

    其他的代码也没有,你是如何调用的不知道,单就InQueue这个函数看,cmd参数是引用参数,传进来的是个地址,在调用InQueue的位置,如果你传入的是个局部变量cmd_Struct,在调用函数结束后cmd_Struct会被清空,但在你覆盖cmd_Struct局部变量所在的内存之前,InQueue中的cmd依然指向有意义的,就是说虽然cmd实际已经变成野指针了,但指向的数据可能依然是cmd_Struct结构,如果新加入的cmd_Struct覆盖了以前加入cmd_Struct的内存,则所有加入的cmd都指向了最后一次加入的cmd_Struct结构,不知这么说你明白不。
    string是一种特殊的指针,它有引用计数,所以用string不会出现问题。
    建议你还是看看TLIST的代码,入队的一定要是个原对象的拷贝,不能只是个地址。
      

  5.   

    结构里放string(而不是string[123])才会出问题。
    好像现象说反了
      

  6.   

    在FormCreate 中会初始化 InitDataQueue;调用过程很简单procedure TForm1.Button1Click(Sender: TObject);
    var
      tDataStruct:Data_Struct;
      t_commdata:Tcomdata;
      tstr:string;
    begin
      setlength(t_commdata,1);
      t_commdata[0,0] := '0';
      t_commdata[0,1] := '0';
      tDataStruct.pID := 1;
      tDataStruct.CmdBuf := t_commdata;
      InDataQueue(DataQueue,tDataStruct);  t_commdata[0,0] := '1';
      t_commdata[0,1] := '1';
      tDataStruct.pID := 2 ;
      tDataStruct.CmdBuf := t_commdata;
      InDataQueue(DataQueue,tDataStruct);
    end;针对这个代码,如何改动呢??
      

  7.   

    to sz_haitao经过测试,采用string 完全正常的。。
      

  8.   


    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TcomData = array of array[0..2] of string;  Cmd_Struct = record
        pID: integer;
        CmdBuf: Tcomdata; //Tcomdata; 问题就在这里,如果采用string,则完全正常,如果采用Tcomdata类型,则队列中所有的Cmdarr值都会变成最后一次入队的那个值
      end;  Send_Queue = record
        CmdArr: Array [1..1024] of Cmd_Struct;
        Pos: integer;
        Num: integer;
      end;  TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      Queue: Send_Queue;implementation{$R *.dfm}function InQueue(var Queue: Send_Queue; var Cmd: cmd_Struct) : Boolean;
    begin
      if Queue.Num<1024 then
      begin
        Queue.Num := Queue.Num+1;
        Queue.CmdArr[Queue.Num] := Cmd;
        Result := true;
      end
      else
      begin
        Result := false;
        Exit;
      end;
    end;function OutQueue(var Queue: Send_Queue; var Cmd: cmd_Struct): string;
    var
      I: Integer;
    begin
      if Queue.Num > 0 then
      begin
        Cmd:=Queue.CmdArr[Queue.Pos];
        for I := 1 to Queue.Num + 1 do
        begin
          Queue.CmdArr[i] := Queue.CmdArr[i+1];
        end;
        Queue.Num := Queue.Num-1;
       end
       else
       begin
        Queue.Num:=0;
        Queue.Pos:=1;
        Result:='';
        Exit;
      end;
    end;procedure InitQueue(var Queue: Send_Queue);
    begin
      Queue.Num:=0;
      Queue.Pos:=1;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      InitQueue(Queue);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      C1, C2: Cmd_Struct;
      S1, S2: Send_Queue;
      T1: TcomData;
    begin
      SetLength(T1, 1);
      T1[0][0] := 'T1';
      T1[0][1] := 'T2';
      C1.pID := 0;
      c1.CmdBuf := T1;
      InQueue(Queue, C1);  SetLength(T1, 0);
      SetLength(T1, 1);
      T1[0][0] := 'T3';
      T1[0][1] := 'T4';
      C1.pID := 0;
      c1.CmdBuf := T1;
      InQueue(Queue, C1);
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
      I: Integer;
    begin
      for I := 1 to Queue.Num do
      begin
        ShowMessage(Queue.CmdArr[I].CmdBuf[0, 0]);
        ShowMessage(Queue.CmdArr[I].CmdBuf[0, 1]);
      end;  
    end;end.
      

  9.   

    在入队的时候要先  SetLength(T1, 0);
    然后再分配  SetLength(T1, 1); 再入队
      

  10.   

    InDataQueue(DataQueue,tDataStruct);
    其实你每次传入的tDataStruct.CmdBuf 都是同一个t_commdata,所以后面的覆盖掉前面的了
      

  11.   

    Tks sanguomi  SetLength(T1, 0);
      SetLength(T1, 1);上面2行代码解决了问题。