record 中的 string 会自动释放么??结构体类似如下:我我错了,这块用得少,有空补习下。[解决办法]可以不用手
record 中的 string 会自动释放么?? 结构体类似如下:
我我错了,这块用得少,有空补习下。
[解决办法] 可以不用手动释放。由delphi管理的.
------解决方案--------------------
引用: 1楼误导了. GetMem和FreeMem就需要事先把字符串 := '' 如果是用 New和Dispose则不用 貌似关键是用Dispose来释放。
Delphi 2007 System.Finalize帮助 For global variables, local variables, objects, and dynamic variables deallocated using Dispose, the compiler generates code that finalizes all long strings, variants, and interfaces contained by the variable when the instance is destroyed. 貌似用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确实存在常量字符串的问题,而且从出生到现在一直有包括Delphi2010
XE/XE2没作测试
[解决办法] 4楼这样测试不准确
string 自动释放要 时机
在一个函数内用到 那么在这个函数内是不会自动释放的
完成这个函数后 才会检测释放
[解决办法] 我记得字符串是自动释放的。
[解决办法] GetMem和Dispose也可以,一般不这么配对,习惯上是GetMem/FreeMem,New/Dispose
程序本着谁申请谁释放的原则,如果用GetMem,回过头来看代码的时候,一定要找FreeMem.容易忽略Dispose
[解决办法] 引用: s11ss很认真在研究. 你的方法测试不完全对,不能拿字符串常量来测试这个 给你看个例子: Delphi(Pascal) code var D : integer; procedure TestProc1; var S : AnsiString; begin S := 'abcdefghijklmn'; //这里并未复制一个,而是给常量字符串的引…… 我当时就看调试状态的汇编代码了,我的那段代码会调用LStrAsg,跟进去会发现NewAnsiString,继续跟进去会执行到GetMem,证明确实生成字符串了——所以这儿的字符串常量用来测试没问题!
[解决办法] 不知道没关系,请不要乱说,多看别人怎么说的,或者动手试验一下。不是指1楼.
[解决办法] 我的环境是Delphi2007,测试那个TestProc1也是会生成新的字符串,并且在S:=''的时候调用了LStrClr。
不知道Delphi7是不是也是这样。
[解决办法] 引用: 我的环境是Delphi2007,测试那个TestProc1也是会生成新的字符串,并且在S:=''的时候调用了LStrClr。 不知道Delphi7是不是也是这样。
纠错。。。虽然调用了LStrAsg,但是并没有执行到NewAnsiString,所以没生成新的字符串。。。
[解决办法] 引用: 引用: 我的环境是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:
[解决办法] 引用: 不知道没关系,请不要乱说,多看别人怎么说的,或者动手试验一下。不是指1楼. 是说我么? 好吧 我承认 我没有测试
但是呢 你这样测试 不够准确 这个观点我还是坚持,至于你测出的结果与事实对于不对,我就不知了,我承认没深入了解
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就行了