主程序
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的值呢?还请各位大大指点一下,谢谢!
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的值呢?还请各位大大指点一下,谢谢!
解决方案 »
- clientdataset.refresh后出现的问题?
- 在代码中把DBGrid.options中的dgRowselect由false改为true,请贴出代码.
- delphixe中关于pchar的问题
- delphi最拿手的是什么语言(垃圾请不要答)
- 超级市场pos机系统软件!
- 帮帮忙
- 求Delphi5.0
- 谁能给我一个面向对象软件设计的一个Hello World!(300分),不够在加,谢谢!详细情况见里面。
- 这句SQL 怎么写? (SQL SERVER)
- 一个简单的问题-怎样在DELPHI中调用EXCEL和WORD??
- 请高手求解:动态生成树与DBGird结合,联动的问题!
- delphi frame的问题
其实在内存中还是按字符串格式存储的?应该不是这个问题
你在赋值后立刻检查,它是指向了一个正常的值,但一离开当前的方法,这些指针所指向的位置的数据都已经
释放了。而用第二种方法,GetMem(p,Length(IntToStr(i))+1); 是在全局堆中分配了一块内存,除非你主动释放,否则它的生命期和整个程序的生命期一样。建议你在使用 数组的时候使用record ,如果要是用TList,还是将它定义为 class 吧,这样使用上能方便一些
a: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类型是生存期自管理类型,当退出这个过程的时候它就自动释放了,所以你再访问这里的内容就不存在,以至于出现乱码
Test=record
a:pchar;
end; ==》PTest=^Test
Test=record
a:array[1.255] of char;
end; 这样试试