返回信息流string 的内存是怎么分配和释放的
如果我这样写
string a=".. ";//一个巨长的字符串
a="b";
a会释放一部分多余的内存么
这是一条镜像帖。来源:北邮人论坛 / cpp / #44922同步于 2010/10/18
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
关于string的问题
lockhart
2010/10/18镜像同步9 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
之前的对象被销毁了...然后又构造了一个新的对象...
【 在 lockhart 的大作中提到: 】
: string 的内存是怎么分配和释放的
: 如果我这样写
: string a=".. ";//一个巨长的字符串
: ...................
以下测试在vs2008,DEBUG模式下进行。
Code:
#include <string>
using namespace std;
void main()
{
string a="sdfasdfasdfasdfas";
a= "b";
}
运行结果见图:
第一步:
可以看到字符串被保存到内存地址0x3963f0处
再继续运行:
可以发现,其实并没有把前面那个字符串释放,而只是修改了第一字节,然后在后面加了\0而已。
同样的测试方法,还做了以下测试:
如果a是一个很短的string,那么它将会放到栈里(调试器显示_Ptr是Bad_Ptr,而数据是放到了_Buf里)。进行a=AnotherString赋值时,如果AnotherString过长,将会被放到_Ptr指向的地址,如果还是很短,会继续在_Buf指向的栈的地址往后写(貌似在申请栈空间时已经申请了一定量足够大的空间,超出此大小才会往_Ptr指向的地址存放)
如果a是一个较长的string(长到没有被放到栈里),进行a=AnotherString赋值时,AnotherString是一个更长的字符串,则如果比原串只是长一点,就会直接在原地址覆盖(看来是在初始化时就已经申请了一个大于原string的空间。)。但是比原字符串长很多(多申请的空间还是不够)原字符串会被释放,然后重新申请一个足够大的空间来存放新字符串。
【 在 smilefufu 的大作中提到: 】
: 同样的测试方法,还做了以下测试:
: 如果a是一个很短的string,那么它将会放到栈里(调试器显示_Ptr是Bad_Ptr,而数据是放到了_Buf里)。进行a=AnotherString赋值时,如果AnotherString过长,将会被放到_Ptr指向的地址,如果还是很短,会继续在_Buf指向的栈的地址往后写(貌似在申请栈空间时已经申请了一定量足够大的空间,超出此大小才会往_Ptr指向的地址存放)
: 如果a是一个较长的string(长到没有被放到栈里),进行a=AnotherString赋值时,AnotherString是一个更长的字符串,则如果比原串只是长一点,就会直接在原地址覆盖(看来是在初始化时就已经申请了一个大于原string的空间。)。但是比原字符串长很多(多申请的空间还是不够)原字符串会被释放,然后重新申请一个足够大的空间来存放新字符串。
谢谢 我想问一下如果字符串长到一定程度 比如10w 再重新赋值为“a” 会重新分配内存么
呃,10w个字符么?那就是大约100KB吧。从上面的测试来看的话,如果重新赋值的字符串小于等于10w,则不会重新分配(略大于也不会,只要不超出预先多分配的空间是就不会重新分配。但具体编译器在编译的时候,为字符串多分配了多少空间我并不知道……我没有做实验研究……)。面如果大于10w很多,超出预先多分配的空间了,就会释放原内存,再重新分配内存的。
另外要强调一下的是,我这个结论只能保证在vs2008的编译环境下是正确的,其他编译器有可能会有不同的实现方式,当然也有可能是一致的。
【 在 lockhart 的大作中提到: 】
:
: 【 在 smilefufu 的大作中提到: 】
: : 同样的测试方法,还做了以下测试:
: ...................
差不多,string的处理基本上就是这样的,赞同
【 在 smilefufu 的大作中提到: 】
: 同样的测试方法,还做了以下测试:
: 如果a是一个很短的string,那么它将会放到栈里(调试器显示_Ptr是Bad_Ptr,而数据是放到了_Buf里)。进行a=AnotherString赋值时,如果AnotherString过长,将会被放到_Ptr指向的地址,如果还是很短,会继续在_Buf指向的栈的地址往后写(貌似在申请栈空间时已经申请了一定量足够大的空间,超出此大小才会往_Ptr指向的地址存放)
: 如果a是一个较长的string(长到没有被放到栈里),进行a=AnotherString赋值时,AnotherString是一个更长的字符串,则如果比原串只是长一点,就会直接在原地址覆盖(看来是在初始化时就已经申请了一个大于原string的空间。)。但是比原字符串长很多(多申请的空间还是不够)原字符串会被释放,然后重新申请一个足够大的空间来存放新字符串。
: ...................