首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

record 中的 string 能自动释放么?

2012-08-01 
record 中的 string 会自动释放么??结构体类似如下:Delphi(Pascal) codeRRecord recordEndTime:TDateTim

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管理的.
[解决办法]
探讨
1楼误导了.

GetMem和FreeMem就需要事先把字符串 := ''
如果是用
New和Dispose则不用

[解决办法]
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
[解决办法]

探讨
s11ss很认真在研究.
你的方法测试不完全对,不能拿字符串常量来测试这个
给你看个例子:

Delphi(Pascal) code


var
D : integer;

procedure TestProc1;
var
S : AnsiString;
begin
S := 'abcdefghijklmn'; //这里并未复制一个,而是给常量字符串的引……

[解决办法]
不知道没关系,请不要乱说,多看别人怎么说的,或者动手试验一下。不是指1楼.
[解决办法]
我的环境是Delphi2007,测试那个TestProc1也是会生成新的字符串,并且在S:=''的时候调用了LStrClr。
不知道Delphi7是不是也是这样。
[解决办法]
探讨
我的环境是Delphi2007,测试那个TestProc1也是会生成新的字符串,并且在S:=''的时候调用了LStrClr。
不知道Delphi7是不是也是这样。

[解决办法]
探讨
引用:
我的环境是Delphi2007,测试那个TestProc1也是会生成新的字符串,并且在S:=''的时候调用了LStrClr。
不知道Delphi7是不是也是这样。

纠错。。。虽然调用了LStrAsg,但是并没有执行到NewAnsiString,所以没生成新的字符串。。。

[解决办法]
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楼.

[解决办法]
爱咋理解咋理解,没空跟你耗
[解决办法]
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就行了

热点排行