record 中的 string 会自动释放么??
结构体类似如下:
[解决办法]
可以不用手动释放。由delphi管理的.
------解决方案--------------------
貌似关键是用Dispose来释放。
貌似用GetMem和Dispose的组合也可以——New内部调用了GetMem, 然后调用System.Initialize,就是把字符串、接口什么的清零。
[解决办法]
s11ss很认真在研究.
你的方法测试不完全对,不能拿字符串常量来测试这个
给你看个例子:
var
D : integer;
procedure TestProc1;
var
S : AnsiString;
begin
S := 'abcdefghijklmn'; //这里并未复制一个,而是给常量字符串的引用+1
D := Integer(S);
S := ''; //引用-1,并未释放 abcd...占的内存,实际上释放不了,它在只读内存区,靠
end;
procedure TestProc2;
var
S : AnsiString;
begin
SetLength(S , 20); //生成一个全新的字符串,一定是全新的从堆上分配的.
S := 'abc' + S;
D := Integer(S);
S := ''; //这里就真正释放了,所以后面调用D要出错.
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TestProc1;
ShowMessage(AnsiString(D)); //这个不出错,但是显示的是 abcdefghijklmn
TestProc2;
ShowMessage(AnsiString(D)); //这个就要出错了.
end;
这虽然不是Delphi本身的问题,但是Delphi确实存在常量字符串的问题,而且从出生到现在一直有包—elphi2010
XE/XE2没作测试
[解决办法]
4楼这样测试不准确
string 自动释放要 时机
在一个函数内用到 那么在这个函数内是不会自动释放的
完成这个函数后 才会检测释放
[解决办法]
我记得字符串是自动释放的。
[解决办法]
GetMem和Dispose也可以,一般不这么配对,习惯上是GetMem/FreeMem,New/Dispose
程序本着谁申请谁释放的原则,如果用GetMem,回过头来看代码的时候,一定要找FreeMem.容易忽略Dispose
[解决办法]
我当时就看调试状态的汇编代码了,我的那段代码会调用LStrAsg,跟进去会发现NewAnsiString,继续跟进去会执行到GetMem,证明确实生成字符串了——所以这儿的字符串常量用来测试没问题!
[解决办法]
不知道没关系,请不要乱说,多看别人怎么说的,或者动手试验一下。不是指1楼.
[解决办法]
我的环境是Delphi2007,测试那个TestProc1也是会生成新的字符串,并且在S:=''的时候调用了LStrClr。
不知道Delphi7是不是也是这样。
[解决办法]
纠错。。。虽然调用了LStrAsg,但是并没有执行到NewAnsiString,所以没生成新的字符串。。。
[解决办法]
。。。是LStrLAsg
[解决办法]
procedure TestProc1;
var
S : AnsiString;
begin
S := 'abcdefghijklmn';
PByte(S)^ := 0; //出错,证明未复制新串,D7,D2010是这样,2007未测试,下班了,
[解决办法]
To 9L:
既然在只读内存区,那为什么引用计数可以修改?在S := 'abcdefghijklmn'之后,引用计数变成了0,之前是-1.
[解决办法]
Sorry,那里没有对引用记数操作,常量字符串的记数为$FFFFFFFF
procedure _LStrClr(var S);
MOV ECX,[EDX-skew].StrRec.refCnt { fetch refCnt }
DEC ECX { if < 0: literal str }
JL @@done //常量字符串到这里就跳转了
......
@@done:
[解决办法]
是说我么? 好吧 我承认 我没有测试
但是呢 你这样测试 不够准确 这个观点我还是坚持,至于你测出的结果与事实对于不对,我就不知了,我承认没深入了解
s11ss 的测试 在另一个button 事件里 显示信息 从语义上来说 比较准确
语义准确了 并不代表测试的结果也会正确!
你只要了解为什么出现 FreeAndNil 这个函数,大概就知道为什么了
对于引用计数的机制
我的理解是:系统在某个时刻,进行全局扫描,打引用计数为0的内在释放
那是在什么时刻比较好呢 ?据说是处理完本次事件的下一次事件开始
关于string 类型 找到一篇文章
共同学习下
http://www.cnblogs.com/zhengjuzhuan/archive/2010/03/15/1686257.html
[解决办法]
爱咋理解咋理解,没空跟你耗
[解决办法]
type
t1 = record
f1:string;
f2: variant;
f3: IInterface
end;
...
var
p:^t1;
begin
new(p); //这句等价于 Getmem(p,sizeof(t1)); Initialize(p^);
dispose(p); //这句等价于 Finalize(p^),FreeMem(p,sizeof(t1));
...
对于string,variant,inteface这三种“号称”内存自管理的变量类型,Getmem和FreeMem太低阶了,不会顾及他的一些引用计数。
[解决办法]
短字符串才会自动释放: s:string[x]; //1<x<255
[解决办法]
http://www.cnblogs.com/zhengjuzhuan/archive/2010/03/15/1686257.html
里 说得很清楚 推荐这文章
反正 结果就是 FreeMem 要手功释放 Dispose不用
[解决办法]
用New+Dispose就行了