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个非常奇怪的问题,就是上面代码中添加注释的那句会影响到引用计数。不知各位对这个是怎样理解的,请教、

解决方案 »

  1. 看了你的结贴率, 都不知道该不该回了, :)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'不是一个地址了, 引用数也不一样了.
      

  2. @str1[1]会使strl重新分配内存,所以地址,引用计数等肯定都不一样了
      

  3. 首先感谢这么仁兄的细心回答,但是我要说1句:你不要怀疑哥的结贴率,因为80%并不代表我的诚信度有问题这个账号是07年注册,但是最近1个月才经常上这个坛子。由于在发这个帖子之前发了1个帖子没有接(2者时间很短,打算一起接的),所以造成结贴率只80%(这个我并不知道csdn还有如此判断用户结贴率的)
      

aliyun

类似问题 »