string的迷惑,感觉很奇怪的1个问题

kfcoffe 2010-01-12 09:22:11

var
str1 ,str2: string;

procedure TForm1.Button1Click(Sender: TObject);
begin
str1 := 'abcd';
str2 := str1;
Memo1.Lines.Add(IntToStr(Integer(@str1[1]))) ; //注释掉这句和添加这句对结果影响很大。
Memo1.Lines.Add(IntToStr(Integer(str1))) ;
Memo1.Lines.Add(
'str1 Address: ' + IntToStr(Integer(str1)) + #13#10 +
'str1 Reference: ' + IntToStr(PInteger(Integer(str1) - 8)^) + #13#10 +
'str1 Value: ' + str1 + #13#10 +
'str2 Address: ' + IntToStr(Integer(str2)) + #13#10 +
'str2 Reference: ' + IntToStr(PInteger(Integer(str2) - 8)^) + #13#10 +
'str2 Value: ' + str2 + #13#10
);

str2 := '1234';
Memo1.Lines.Add('str2 := ''1234''');
Memo1.Lines.Add(
'str1 Address: ' + IntToStr(Integer(str1)) + #13#10 +
'str1 Reference: ' + IntToStr(PInteger(Integer(str1) - 8)^) + #13#10 +
'str1 Value: ' + str1 + #13#10 +
'str2 Address: ' + IntToStr(Integer(str2)) + #13#10 +
'str2 Reference: ' + IntToStr(PInteger(Integer(str2) - 8)^) + #13#10 +
'str2 Value: ' + str2 + #13#10
);
end;


刚才在测试string引用计数的时候发现1个非常奇怪的问题,就是上面代码中添加注释的那句会影响到引用计数。不知各位对这个是怎样理解的,请教、

...全文
103 点赞 收藏 7
写回复
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
dd_zhouqian 2010-01-13
mark,纯学习
回复
kfcoffe 2010-01-13
[Quote=引用 3 楼 hexpate 的回复:]
看了你的结贴率, 都不知道该不该回了, :)

str1 := 'abcd';中的'abcd'可以看作是常量, 他的引用计数为-1;
这里的赋值只是简单的将str1指向存放abcd的地址, 这个地址-$8 是引用计数 -1; 当你注释掉那句话的时候肯定显示引用计数为-1, 且str2和str1一样, str2和str1是同样的道理

为什么你不注释的时候会有问题, 那是因为@str1[1] 的操作会引发UniqueString操作, 这个过程里,delphi检查如果引用计数-1 <>0 则单独分配一块内存, 并拷贝str1指向的内存,也就是abcd, 并且设置新的地址中-$8的位置为1 也就是新的字符串引用计数为1. 故此你看到的地址就和真正原始的'abcd'不是一个地址了, 引用数也不一样了.
[/Quote]
首先感谢这么仁兄的细心回答,但是我要说1句:你不要怀疑哥的结贴率,因为80%并不代表我的诚信度有问题这个账号是07年注册,但是最近1个月才经常上这个坛子。由于在发这个帖子之前发了1个帖子没有接(2者时间很短,打算一起接的),所以造成结贴率只80%(这个我并不知道csdn还有如此判断用户结贴率的)
回复
wzwcn 2010-01-13
@str1[1]会使strl重新分配内存,所以地址,引用计数等肯定都不一样了
回复
林石公 2010-01-13
嗯,这个以前讨论过
回复
Hexpate 2010-01-13
看了你的结贴率, 都不知道该不该回了, :)

str1 := 'abcd';中的'abcd'可以看作是常量, 他的引用计数为-1;
这里的赋值只是简单的将str1指向存放abcd的地址, 这个地址-$8 是引用计数 -1; 当你注释掉那句话的时候肯定显示引用计数为-1, 且str2和str1一样, str2和str1是同样的道理

为什么你不注释的时候会有问题, 那是因为@str1[1] 的操作会引发UniqueString操作, 这个过程里,delphi检查如果引用计数-1 <>0 则单独分配一块内存, 并拷贝str1指向的内存,也就是abcd, 并且设置新的地址中-$8的位置为1 也就是新的字符串引用计数为1. 故此你看到的地址就和真正原始的'abcd'不是一个地址了, 引用数也不一样了.
回复
kfcoffe 2010-01-12
string 的引用计数。
回复
Frank.WU 2010-01-12
ascii ?
回复
发动态
发帖子
语言基础/算法/系统设计
创建于2007-08-02

1.6w+

社区成员

Delphi 语言基础/算法/系统设计
申请成为版主
社区公告
暂无公告