在程序中直接使用字符串常量如"abc"到底会不会引起内存泄漏??
记得以前好像看过说直接在程序中使用字符串常量会引起内存泄漏,到底是不是这样??今天看ACE类库的Example,看到不少直接使用字符串的,不知道到底有没有问题??
拷两句过来:
ACE_OS::strcat (filename, ".log");
}
else
ACE_OS::strcpy (filename, "logging_server.log");
问题点数:60、回复次数:23Top
1 楼qhfu(改个名字)回复于 2006-02-19 14:48:21 得分 10
安全Top
2 楼iamcaicainiao(老菜,长征)回复于 2006-02-19 15:27:57 得分 10
没有问题,尽管使用.Top
3 楼yiyuan(一元)回复于 2006-02-19 15:39:16 得分 0
看来是没有问题的。但如果在一个循环里,是不是这样就会分配给字符串大量内存?比如这样的
for (int i = 0; i < 1000000; i++)
{
....
ACE_OS::strcat (filename, ".log");
}
".log"会不会被重复分配大量内存??Top
4 楼du51(郁郁思扬)回复于 2006-02-19 19:21:09 得分 0
".log"会不会被重复分配大量内存??
会的.Top
5 楼zhousqy(标准C匪徒)(甩拉,甩拉)回复于 2006-02-19 20:00:17 得分 0
不会,相同的常量应该只有1个Top
6 楼lonelyforest(一生所爱)回复于 2006-02-19 20:06:50 得分 10
不用担心, 理论上,只有 经过了 new / malloc 的地方才有可能泄漏内存,需要释放,这个常量是编译的时候分配的, 这种常量应该只有一个, 在一个域内,所以可能会导致你的程序庞大,却不会导致你的内存泄漏!! 呵呵, 放心使用吧! 如果你还不放心,那么这种东西怎么释放呢?? 你想想!! 是系统回收的!!Top
7 楼ugg(逸学堂(exuetang.net))回复于 2006-02-19 21:06:28 得分 0
没有问题Top
8 楼eric8231(1328cire)回复于 2006-02-19 22:03:33 得分 0
字符串常量分配在静态存储区,这个区域中内存资源在整个程序退出前才释放。你那个循环,应该是只分配一个字符串的副本。Top
9 楼redf0x_1(雪逸红狐)回复于 2006-02-19 23:42:21 得分 0
像你那样循环的话应该会重复分配内存,因此程序会占用大量的静态存储区
楼上有说不会引起重复分配的,难道你用一个字符串常量的时候编译器或者说系统还会给你比较静态存储区是否有相同的字符串存在么?这显然是不可能的
如果要确认,你可以用一下语句
if("test"=="test")
验证,答案当然是false,原因就是它们所存在的内存地址不同Top
10 楼du51(郁郁思扬)回复于 2006-02-19 23:48:16 得分 0
楼上强人.
顶.Top
11 楼ericqxg007(还有很多东西要学(卡卡一米阳光))回复于 2006-02-20 00:11:05 得分 0
楼主要弄明白到底怎样才算内存泄漏~
如果程序运行到最后可以安全的收回该程序分配或使用了的内存,那么就不存在所谓的内存泄漏的问题。显然字符串常量是在静态存储区中分配内存的所以,程序结束后会自动收回分配的内存,因此也就不存在内存泄漏的问题了Top
12 楼YufengShi(浪子)回复于 2006-02-20 00:40:05 得分 0
to redf0x_1(雪逸红狐):
if("test"=="test")
验证,答案当然是false,原因就是它们所存在的内存地址不同
-------------------------------------------------------
答案是true,环境vc6.0 debugTop
13 楼eric8231(1328cire)回复于 2006-02-20 01:38:26 得分 0
实际上,("test"=="test")的结果是true 还是false,是由编译器来决定的,并不是由语言本身决定的。换言之,C++标准并没有规定两个“字面值”相同的字符串常量是否该储存为一个单一的副本。
至于LZ给出的那个循环:
for (int i = 0; i < 1000000; i++)
{
....
ACE_OS::strcat (filename, ".log");
}
考虑到这段程序本身的流程,所以我觉得对于一般的编译器,至少可以做到“避免对每一次跌跌代都产生一个字符串常量的副本”。Top
14 楼fine10000(好心情)回复于 2006-02-20 08:35:47 得分 0
没有问题
Top
15 楼DiabloWalkOnTheEarth(我想到个绝妙的昵称,只是地方太小,写不下)回复于 2006-02-20 09:00:41 得分 0
没有问题
Top
16 楼wshcdr(dd)回复于 2006-02-20 11:30:52 得分 0
同意所有楼上意见Top
17 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-02-20 11:33:46 得分 0
不知道说什么好~Top
18 楼OpenHero(开勇)回复于 2006-02-20 11:46:45 得分 0
静态区,markTop
19 楼clzi(楚浪子-我要变强!)回复于 2006-02-20 11:58:33 得分 0
学习Top
20 楼Darkay_Lee()回复于 2006-02-20 12:17:38 得分 0
字符串常量是编译器编译时候分配好的,不是动态生成的东西不存在泄漏的说法。Top
21 楼weis_mai(浮云)回复于 2006-02-20 13:55:42 得分 30
静态量不存在内存泄漏问题的,所有的常量,包括const 定义的常量都是由编译器直接分配的,如果是在机器字可以表示的范围内的常量,会被编译成直接量来使用。
如i=86;那么在内存中根本不会存在一个保存着86的单元。
甚至const i=86;则存在中连这个i的内存单元也是不存在的,编译会在所以使用i的地方换成直接量86,如j=i;会被编译成mov ax,86;其中假设j被放到寄存器ax中。
而字符串之所以特殊一些是因为它往往是用一片内存块来保存,但是它和所有的常量一样是编译器分配的静态内存,只是不同的编译器有不同的解决方案。
有一些编译开关可以对内存分配进行优化,这时它会比较静态字符串中是否有相同的,相同的只存在一个复本。
也有一些编译器不作这个优化,而是在编译到字符串常量时就分配存储单元。但是这个分配只在编译时发生,不会在运行时发生,也就是说,如果是
if ("test"=="test");
则存在两个静态串,"test"和"test",对于循环,如果是
strcpy(des,"test");
strcpy(des,"test");
strcpy(des,"test");
则存在三个静态串,写成
for (i=0;i<3;++i) strcpy(des,"test");
就只有一个静态串,"test"
这是因为在第一个例子中,编译器两次碰到了字符串常量,而第二个例子中碰到三次,但是是在第三个例子中,编译器只碰到一次。编译器可不会在编译for语句时跟着编译三次。
Top
22 楼losedxyz(我真的一无所有)回复于 2006-02-20 14:45:48 得分 0
mark
Top
23 楼xinxinglc(非)回复于 2006-02-20 15:40:34 得分 0
静态量不存在内存泄漏问题的,所有的常量,包括const 定义的常量都是由编译器直接分配的,如果是在机器字可以表示的范围内的常量,会被编译成直接量来使用。
如i=86;那么在内存中根本不会存在一个保存着86的单元。
甚至const i=86;则存在中连这个i的内存单元也是不存在的,编译会在所以使用i的地方换成直接量86,如j=i;会被编译成mov ax,86;其中假设j被放到寄存器ax中。
而字符串之所以特殊一些是因为它往往是用一片内存块来保存,但是它和所有的常量一样是编译器分配的静态内存,只是不同的编译器有不同的解决方案。
有一些编译开关可以对内存分配进行优化,这时它会比较静态字符串中是否有相同的,相同的只存在一个复本。
也有一些编译器不作这个优化,而是在编译到字符串常量时就分配存储单元。但是这个分配只在编译时发生,不会在运行时发生,也就是说,如果是
if ("test"=="test");
则存在两个静态串,"test"和"test",对于循环,如果是
strcpy(des,"test");
strcpy(des,"test");
strcpy(des,"test");
则存在三个静态串,写成
for (i=0;i<3;++i) strcpy(des,"test");
就只有一个静态串,"test"
这是因为在第一个例子中,编译器两次碰到了字符串常量,而第二个例子中碰到三次,但是是在第三个例子中,编译器只碰到一次。编译器可不会在编译for语句时跟着编译三次。
===================================================================================
讲得很有道理呵。Top




