record 中的 string 会自动释放么??
结构体类似如下:
- Delphi(Pascal) code
RRecord = record EndTime :TDateTime; StartTime :TDateTime; i1 :integer; i2 :integer; i3 :integer; i4 :integer; i5 :integer; i6 :integer; s1 :string; s2 :string; s3 :string;end;
假设情况如下:
某时刻程序动态申请内存空间 “GetMem(p, sizeof(RRecord)); ” 。
然后程序有这样的赋值操作 :
p.s1 := ......; p.s2 := ......; p.s3 := ......;
代码跑了一段时间,释放申请的内存空间,程序这样做 :
FreeMem(p, sizeof(RRecord));
请问 FreeMem 时 ,原本里面的s1,s2,s3会自己自动释放么??还是说到程序退出时才自动释放??
需要自己手动释放么??如何释放??
[解决办法]
GetMem(p, sizeof(RRecord))//申请了s1,s2,s3所需的内存空间。
FreeMem(p, sizeof(RRecord));//释放了s1,s2,s3所需的内存空间。
所以是不用的。
[解决办法]
1楼误导了.
GetMem和FreeMem就需要事先把字符串 := ''
如果是用
New和Dispose则不用
[解决办法]
你可以试验一下不就明白了
GetMem(p, sizeof(RRecord));
SetLength(P.s1 , 10 * 1024*1024);
PByte(P.s1)^ := 0;
ShowMessage('看看程序使用的内存,应该>10M');
FreeMem(P);
ShowMessage('现在看看程序使用的内存,应该还是>10M');
然后换成这样
New(p);
SetLength(P.s1 , 10 * 1024*1024);
PByte(P.s1)^ := 0;
ShowMessage('看看程序使用的内存,应该>10M');
Dispose(P);
ShowMessage('现在看看程序使用的内存,应该明显减少了10M');
或者这样
GetMem(p, sizeof(RRecord));
SetLength(P.s1 , 10 * 1024*1024);
PByte(P.s1)^ := 0;
ShowMessage('看看程序使用的内存,应该>10M');
P.s1 := ''; //把字符串释放掉
FreeMem(P);
ShowMessage('现在看看程序使用的内存,应该明显减少了10M');
[解决办法]
我这里测试结果是,需要手动释放,赋值空字符串就行。
- Delphi(Pascal) code
type R = record I: Integer; S: string; end;procedure TForm1.Button1Click(Sender: TObject);begin ShowMessage(string(Tag));end;procedure TForm1.FormCreate(Sender: TObject);var P: ^R;begin GetMem(P, SizeOf(R)); P^.I := 1; P^.S := 'abc'; Tag := Integer(P^.S); ShowMessage(P^.S); //P^.S := '';//如果这里没有手动释放,则点击Button1时,还是会显示abc。从调试状态下的汇编代码中也不会看到用来释放字符串的LStrClr。 FreeMem(P, SizeOf(R));end;
[解决办法]
我我错了,这块用得少,有空补习下。
[解决办法]
可以不用手动释放。由delphi管理的.
[解决办法]
[解决办法]
s11ss很认真在研究.
你的方法测试不完全对,不能拿字符串常量来测试这个
给你看个例子:
- Delphi(Pascal) code
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;
[解决办法]
4楼这样测试不准确
string 自动释放要 时机
在一个函数内用到 那么在这个函数内是不会自动释放的
完成这个函数后 才会检测释放
[解决办法]
我记得字符串是自动释放的。
[解决办法]
GetMem和Dispose也可以,一般不这么配对,习惯上是GetMem/FreeMem,New/Dispose
程序本着谁申请谁释放的原则,如果用GetMem,回过头来看代码的时候,一定要找FreeMem.容易忽略Dispose
[解决办法]
[解决办法]
不知道没关系,请不要乱说,多看别人怎么说的,或者动手试验一下。不是指1楼.
[解决办法]
我的环境是Delphi2007,测试那个TestProc1也是会生成新的字符串,并且在S:=''的时候调用了LStrClr。
不知道Delphi7是不是也是这样。
[解决办法]
[解决办法]
[解决办法]
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:
[解决办法]
[解决办法]
爱咋理解咋理解,没空跟你耗
[解决办法]
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就行了