主程序
 PTest=^Test
 Test=record
    a:pchar;
 end; var
    i:integer;
    t:PTest;
    tt:ThreadList;
    tl:TList;
 begin
    tt:=ThreadList.create;
    tl=tt.locklist;
    for i:=0 to 1000 do
    begin
    new(t);
    t^.a:=Pchar(Inttostr(i));
    showmessage(t^.a);   //这里显示正常的数值i
    tl.add(t);
    end
    tt.unlocklist;
  end;在线程中读取该tt列表procedure TTestThread.Execute;
var
  ts:TStringList;
  thl:Tlist;
begin
  thl:=tt.locklist;
  ts:=TStringList.create;
  for i:=0 to 1000 do
  begin
    ts.items.add(Ptest(thl.items[0])^.a);   //但在ts中的各项都是一些乱码
  end;
  thl.unlocklist;
end;而当我用下面代码添加主程序中循环那段代码时,在线程中的ts项就显示正常
 var
    p:pchar;
    i:integer;
    t:PTest;
    tt:ThreadList;
    tl:TList;
 begin
    tt:=ThreadList.create;
    tl=tt.locklist;
    for i:=0 to 1000 do
    begin
        GetMem(p,Length(IntToStr(i))+1);
        ZeroMemory(p,Length(IntToStr(i))+1);
        StrPCopy(p,IntToStr(i));
    new(t);
    t^.a:=p;
    showmessage(t^.a);   //这里显示正常的数值i
    tl.add(t);
    end
    tt.unlocklist;
  end;为何在最上面那段代码中我使用了强制转换为pchar,而在线程中的ts列表项中都是一些乱码?
这里的强制转换是不是就是暂时欺骗一下骗译器,让其通过存储inttostr(i)到t^.a中,
其实在内存中还是按字符串格式存储的?也就是带有长度+计数器?
但如果是按我上面的想法,为何在主程序中的showmessage又能正常显示出t^.a的值呢?还请各位大大指点一下,谢谢!

解决方案 »

  1.   

    这里的强制转换是不是就是暂时欺骗一下骗译器,让其通过存储inttostr(i)到t^.a中, 
    其实在内存中还是按字符串格式存储的?应该不是这个问题
      

  2.   

    t^.a 是一个指针,t^.a:=Pchar(Inttostr(i)); 只是给这个指针f赋了一个新的地址,就是i 的地址。
    你在赋值后立刻检查,它是指向了一个正常的值,但一离开当前的方法,这些指针所指向的位置的数据都已经
    释放了。而用第二种方法,GetMem(p,Length(IntToStr(i))+1); 是在全局堆中分配了一块内存,除非你主动释放,否则它的生命期和整个程序的生命期一样。建议你在使用 数组的时候使用record ,如果要是用TList,还是将它定义为 class 吧,这样使用上能方便一些
    a:pchar; 也可以考虑定义为 String
      

  3.   

    pchar 与string的区别。
    procedure TForm1.Button1Click(Sender: TObject);
    var
      str : string;
      ss : Pchar;
    begin
      str := 'aa';
      Memo1.Lines.Add(IntToStr(Integer(@str[1]))) ;
      ss := pchar(str);
      Memo1.Lines.Add(IntToStr(Integer(ss))) ;
    end;因为你这里  new(t); 
        t^.a:=Pchar(Inttostr(i)); 赋值仅仅是让t^.a暂时指向了i的地址,并为自己重新分配内存空间
    而delphi  string类型是生存期自管理类型,当退出这个过程的时候它就自动释放了,所以你再访问这里的内容就不存在,以至于出现乱码
      

  4.   

    PTest=^Test
    Test=record
        a:pchar;
    end; ==》PTest=^Test
    Test=record
        a:array[1.255] of char;
    end; 这样试试