局部变量string类型与全局变量string类型的区别 ( 积分: 80 )

  • 主题发起人 主题发起人 sjjwan
  • 开始时间 开始时间
S

sjjwan

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure setvalue;
var
x: string;
y: string;
begin
x := 'skddkk';
x := x + 'adskd';
y := x;
showmessage(y);
end;
我在过程中定义string分配在类型,字符串是哪里的?为什么它不需要引用计数?(发现引用计数为-1)那又是什么时候释放内存的呢?但如果x,y为全局变量,字符串是分配在哪里的呢?它是有引用计数,系统是通过引用计数来决定是否释放内存的。向x := x + 'sksdkdk'又重新指向了内存,'skddkk'字符串是否已释放?如果释放,又是根据什么释放的呢?因为它没有引用计数。
 
String类型的不需要手动释放吧。
全局变量在程序初始化时就创建了。程序结束时释放。
过程或函数里定义的变量在这个过程或函数结束时释放。
 
呵呵,怎么没人回答,热心的朋友帮我解答解答
 
我在过程中定义string分配在类型,字符串是哪里的?
是在堆里
向x := x + 'sksdkdk'又重新指向了内存,'skddkk'字符串是否已释放?
不会释放的
引用计数是-1,说明每当发生字符串的操作,就复制到新的内存,并不是说不用引用计数!!
引用计数由delphi自动管理,没有特别的用途,最好不要修改它,会出现紊乱的!!
 
嘿嘿,有没有说的详细点哦
 
procedure setvalue;
var
x: string;//占用4字节(指针)
y: string;//占用4字节(指针)
begin
//'skddkk'为常量,在内存的只读区,(指针指向它),常量引用计数-1:
//'skddkk'都被你写死在引号里了,它是常量,编译时就确定了,不是动态分配:
x := 'skddkk';
//copy on write分配新内存:
x := x + 'adskd';
//指针指向(为指针赋值):
y := x;
//这才是分配内存,引用计数为1:
SetLength(X,10);
//指针指向(为指针赋值),引用计数为2:
y:=x;
//引用计数不为1,copy on write:
X[1]:='a';
showmessage(y);
end;
 
liuchong:你好
我现已基本明白了意思。
像x: string是局部变量
x := ‘sadgdsg’,字符串是分配在常量区,生命周期是程序开始到程序结束。x直接指向了常量区。
如果x: string是全局变量
x:= 'sadgdsg',其实'sadgdsg'也是分配在常量区,生命周期是程序开始到程序结束。只是系统采用了copy on write,又分配新内存:把常量区的字符串都拷贝过去。x指向了堆区,而不是常量区,所以引用计数为1。
嘿嘿,以上说法是否对的。
 
liuchong:你好
我现已基本明白了意思。
像x: string是局部变量
x := ‘sadgdsg’,字符串是分配在常量区,生命周期是程序开始到程序结束。x直接指向了常量区。
如果x: string是全局变量
x:= 'sadgdsg',其实'sadgdsg'也是分配在常量区,生命周期是程序开始到程序结束。只是系统采用了copy on write,又分配新内存:把常量区的字符串都拷贝过去。x指向了堆区,而不是常量区,所以引用计数为1。
嘿嘿,以上说法是否对的。
 
“像x: string是局部变量
x := ‘sadgdsg’,字符串是分配在常量区,生命周期是程序开始到程序结束。x直接指向了常量区。”
----------------------------------------------
以上正确
----------------------------------------------
“如果x: string是全局变量
x:= 'sadgdsg',其实'sadgdsg'也是分配在常量区,生命周期是程序开始到程序结束。只是系统采用了copy on write,又分配新内存:把常量区的字符串都拷贝过去。x指向了堆区,而不是常量区,所以引用计数为1。”
----------------------------------------------
以上,没有触发copy on write,
当引用计数不为1时,“+”或x[Index]会触发copy on write
只是“:=”不会触发;
直接写死在单引号中的串,是常量,编译期确定的;(就像引用别人的话,加上双引号,引号写死了,里面是不变的)
使用动态分配内存的函数,过程才是动态开辟内存,如:
SetLength,AllocMem,GetMem……
(D7中是这样的,D2007中,直接写x:='abc';这里的'abc'好像不作为常量,我没用D2007,据别人测试得到的说法,感觉D7中的设计更合理)
 
嘿嘿,我好像发现在delphi6中,如:
procedure smaple;
var
x,y: string;
begin
x := 'abc';
y := 'abc';
if integer(x) = integer(y) then
showmessage('ok');
end;
像这里显示ok。他们都是指向了同一地址。但如果把x改为全局变量,就不显示ok。 我想当x为全局变量时, x := 'abc';系统应该是重新分配内存的。
 

procedure smaple;
var
x: string;
p: pchar;
begin
x := 'abc';
p := pchar(x);
p[1] := 'f';
showmessage(x);
end;
则显示为afc,既然是常量区,为什么通过p变量就可以改变啊,常量不是只读的,不能写的吗?真是有点搞不懂。请帮忙解答解答。
 
已经说过了copy on write
修改的是出copy后的,地址变了
 
全局变量在堆上,局部变量在栈上
---------------------------------------------------------------------------------------http://www.waibaoinfo.com 外包信息网 - IT界专业的外包项目信息发布和承接平台
 
我是通过pchar类型的,没有通过string类型。地址没有变。 我做过试验了
 
var
x: string;
p: pchar;
begin
x := 'abc';
p := pchar(x);
p[1] := 'f';//内存错误,(不允许修改),D7
showmessage(x);
end;
 
呵呵,是的。delphi6跟delphi7还是有区别的
delphi6不会发生异常,能修改。
 

Similar threads

回复
0
查看
1K
不得闲
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
后退
顶部