在程序中直接使用字符串常量如"abc"到底会不会引起内存泄漏??

yiyuan 2006-02-19 02:36:49
记得以前好像看过说直接在程序中使用字符串常量会引起内存泄漏,到底是不是这样??今天看ACE类库的Example,看到不少直接使用字符串的,不知道到底有没有问题??
拷两句过来:

ACE_OS::strcat (filename, ".log");
}
else
ACE_OS::strcpy (filename, "logging_server.log");
...全文
619 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
YufengShi 2006-02-20
  • 打赏
  • 举报
回复
to redf0x_1(雪逸红狐):
if("test"=="test")
验证,答案当然是false,原因就是它们所存在的内存地址不同
-------------------------------------------------------
答案是true,环境vc6.0 debug
Darkay_Lee 2006-02-20
  • 打赏
  • 举报
回复
字符串常量是编译器编译时候分配好的,不是动态生成的东西不存在泄漏的说法。
ericqxg007 2006-02-20
  • 打赏
  • 举报
回复
楼主要弄明白到底怎样才算内存泄漏~
如果程序运行到最后可以安全的收回该程序分配或使用了的内存,那么就不存在所谓的内存泄漏的问题。显然字符串常量是在静态存储区中分配内存的所以,程序结束后会自动收回分配的内存,因此也就不存在内存泄漏的问题了
clzi 2006-02-20
  • 打赏
  • 举报
回复
学习
OpenHero 2006-02-20
  • 打赏
  • 举报
回复
静态区,mark
dragonzxh 2006-02-20
  • 打赏
  • 举报
回复
不知道说什么好~
wshcdr 2006-02-20
  • 打赏
  • 举报
回复
同意所有楼上意见
  • 打赏
  • 举报
回复
没有问题
fine10000 2006-02-20
  • 打赏
  • 举报
回复
没有问题
xinxinglc 2006-02-20
  • 打赏
  • 举报
回复
静态量不存在内存泄漏问题的,所有的常量,包括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语句时跟着编译三次。

===================================================================================
讲得很有道理呵。
losedxyz 2006-02-20
  • 打赏
  • 举报
回复
mark
weis_mai 2006-02-20
  • 打赏
  • 举报
回复
静态量不存在内存泄漏问题的,所有的常量,包括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语句时跟着编译三次。
eric8231 2006-02-20
  • 打赏
  • 举报
回复
实际上,("test"=="test")的结果是true 还是false,是由编译器来决定的,并不是由语言本身决定的。换言之,C++标准并没有规定两个“字面值”相同的字符串常量是否该储存为一个单一的副本。

至于LZ给出的那个循环:
for (int i = 0; i < 1000000; i++)
{
....
ACE_OS::strcat (filename, ".log");
}

考虑到这段程序本身的流程,所以我觉得对于一般的编译器,至少可以做到“避免对每一次跌跌代都产生一个字符串常量的副本”。
du51 2006-02-19
  • 打赏
  • 举报
回复
楼上强人.
顶.
redf0x_1 2006-02-19
  • 打赏
  • 举报
回复
像你那样循环的话应该会重复分配内存,因此程序会占用大量的静态存储区
楼上有说不会引起重复分配的,难道你用一个字符串常量的时候编译器或者说系统还会给你比较静态存储区是否有相同的字符串存在么?这显然是不可能的
如果要确认,你可以用一下语句
if("test"=="test")
验证,答案当然是false,原因就是它们所存在的内存地址不同
eric8231 2006-02-19
  • 打赏
  • 举报
回复
字符串常量分配在静态存储区,这个区域中内存资源在整个程序退出前才释放。你那个循环,应该是只分配一个字符串的副本。
逸学堂 2006-02-19
  • 打赏
  • 举报
回复
没有问题
lonelyforest 2006-02-19
  • 打赏
  • 举报
回复
不用担心, 理论上,只有 经过了 new / malloc 的地方才有可能泄漏内存,需要释放,这个常量是编译的时候分配的, 这种常量应该只有一个, 在一个域内,所以可能会导致你的程序庞大,却不会导致你的内存泄漏!! 呵呵, 放心使用吧! 如果你还不放心,那么这种东西怎么释放呢?? 你想想!! 是系统回收的!!
zhousqy 2006-02-19
  • 打赏
  • 举报
回复
不会,相同的常量应该只有1个
du51 2006-02-19
  • 打赏
  • 举报
回复
".log"会不会被重复分配大量内存??
会的.
加载更多回复(3)

64,645

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧