关于string的Copy-On-Write

ckt 2007-09-08 12:08:19
看了篇关于string使用Copy-On-Write的文章:
http://blog.csdn.net/ckt1120/archive/2007/09/08/1777004.aspx

#include <string>
#include <iostream>
using namespace std;
void main()
{
string str1("hello world!");
string str2 = str1;

printf ("Before Copy-On-Write:\n");
printf ("str1's address: %x\n", str1.c_str());
printf ("str2's address: %x\n", str2.c_str());

str1[1] = 'q';
str2[2] = 'g';
string str3 = str2;

printf ("\nAfter Copy-On-Write:\n");
printf ("str1's address: %x\n", str1.c_str());
printf ("str2's address: %x\n", str2.c_str());
printf ("str3's address: %x\n", str3.c_str());
}

有个疑惑想请教:对于str3,我觉得应该是和str2共用一段内存空间,即打印出的地址应该相同。
但是结果却不同?
...全文
385 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
roadtang 2007-09-08
  • 打赏
  • 举报
回复
哦,
VC系统里我也不确定。
不过我可以确定gnu系统里是这样的。
ckt 2007-09-08
  • 打赏
  • 举报
回复
to:roadtang

你讲的:当你的某个string被修改了,库将知道这个string是被更改了,而且会假定这个string以后会再被更改 或者频繁被更改。

和我想法差不多,只是不太肯定是不是。
roadtang 2007-09-08
  • 打赏
  • 举报
回复

我又看了一下, 之前想错了 -_-!

你是对的,如果仅仅是copy-on-write,两种表现是应该一样的。str1变了就是因为copy-on-write了

而实际上真正的表现是不同的, 原因是因为有一种这样的额外的库实现考虑

当你的某个string被修改了,库将知道这个string是被更改了,而且会假定这个string以后会再被更改 或者频繁被更改。
试想我们一向
for (int i=0; i<LEN; i++)
{
s[i] = xxx;
} (不好的风格,just for demo)
很少有单个操作s[1] = x,后就没有了。

实现上,
库会对这样的string做一个标志,使其不参与空间的共享和争用。
任何从其复制构造的string,取得独立的空间,不共享。

在你的测试代码里加上
// str2 is modified (leaked0
string str4 = str3;
string str5 = str2;
printf ("str4's address: %x\n", str4.c_str());
printf ("str5's address: %x\n", str5.c_str());
可以来验证这个。
str3 与 str4相同
str5 还是与str2 不同。

标准库 总是比我们想的远哪.
(我是基于gcc libstdcxx, VC的环境楼主不妨也再测试下)
ckt 2007-09-08
  • 打赏
  • 举报
回复
to:roadtang

str1因为要修改内存里的值,此时内存中的计数引用不为0或1,所以在new一段空间给str1.
所以str1的地址变化了。
str2虽然修改内存的值,但是计数已经为1.所以没有申请新的内存给它。

此次str2初始化str3,我觉得str3应该是和str2指向同一段内存的,该内存的计数增加。
roadtang 2007-09-08
  • 打赏
  • 举报
回复
你好像是觉得
string str1("hello world!");
string str2 = str1;
这是复制构造, 结果显然是没有copy. (用了copy-on-write了)
而string str3 = str2;
这也是复制构造, 结果却是直接copy了。
所以认为表现是不同的。

但是你发现了没有, str1的地址也变化了, 你根本没有引用动str1, 为什么str1却有了和以前不同的值?这可能是更奇怪的一件事情。
ckt 2007-09-08
  • 打赏
  • 举报
回复
我的是VC6.0环境
我疑问的是,这个库在这个编译器环境下
对一种情况的处理不同。一次用copy-on -write,一次没有?
不同的原因在那里
加油馒头 2007-09-08
  • 打赏
  • 举报
回复
你是赋值啊。
又不是string *str3 = &str2 ,这样才会输出一样的。
roadtang 2007-09-08
  • 打赏
  • 举报
回复
copy-on-write是一种实现string的方式,与标准应该无关,
也就是说有些实现可能是copy-on -write, 有些可能根本就没用,
而有些呢,可能判断什么时候write的机制很复杂, 甚至同一个库不同的版本表现可能都不一样。

你是g++, libstdcc的环境吗?
jhs1982419 2007-09-08
  • 打赏
  • 举报
回复
str3为什么是和str2共用一段内存空间呢,我觉得不一定,你只不过是把str2内容给了str3,内存空间为什么非要一样呢.
ckt 2007-09-08
  • 打赏
  • 举报
回复
to:akirya
能讲的详细点吗
  • 打赏
  • 举报
回复
并不是string都是用Copy-On-Write的

65,187

社区成员

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

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