鉴于:
1)C++ 03标准没有以任何方式解决线程的存在
2)C++ 03标准让实现决定是否std::string
应该在其拷贝构造函数中使用Copy-on-Write语义
3)Copy-on-Write语义经常导致多线程程序中不可预测的行为
我得出以下看似有争议的结论:
您无法在多线程程序中安全且可移植地使用std :: string
显然,没有STL数据结构是线程安全的.但至少,使用std :: vector,您可以简单地使用互斥锁来保护对向量的访问.使用使用COW的std :: string实现,如果不在供应商实现中深入编辑引用计数语义,您甚至无法可靠地执行此操作.
现实世界的例子:
在我的公司,我们有一个多线程应用程序,经过彻底的单元测试,无数次通过Valgrind.该应用程序运行了几个月,没有任何问题.有一天,我在另一个版本的gcc上重新编译应用程序,突然之间我总是得到随机的段错误.Valgrind现在在std :: string复制构造函数中报告libstdc ++中的无效内存访问.
那么解决方案是什么?好吧,当然,我可以将typedef std::vector<char>
作为一个字符串类 - 但实际上,这很糟糕.我还可以等待C++ 0x,我祈祷将要求实现者放弃COW.或者,(颤抖),我可以使用自定义字符串类.我个人总是反对在预先存在的库可以正常运行时实现自己的类的开发人员,但老实说,我需要一个字符串类,我可以肯定它不使用COW语义; 和std :: string根本不保证.
我是不是正确的,std::string
根本无法可靠地使用在所有便携式,多线程程序?什么是好的解决方法?
最近我一直在阅读Java子串方法的一些缺陷 - 特别是与内存有关,以及java如何保持对原始字符串的引用.具有讽刺意味的是,我也正在开发一个服务器应用程序,该应用程序在一秒钟内使用C#.Net的子串实现几十次.这让我想到了......
string.Substring
吗?string.Substring
?是否有更快的方法根据开始/结束位置拆分字符串?我正在研究一种高性能代码,其中该构造是性能关键部分的一部分.
这是在某些部分中发生的情况:
string
被"扫描"并且元数据被有效存储.char[][]
.char[][]
应该转移到string[]
.现在,我知道你可以打电话,new string(char[])
但结果必须复制.
为了避免发生这种额外的复制步骤,我想我必须可以直接写入字符串的内部缓冲区.即使这将是一个不安全的操作(我知道这带来了许多影响,如溢出,向前兼容).
我已经看到了实现这一目标的几种方法,但没有一种我真的很满意.
有没有人有关于如何实现这一目标的真实建议?
额外信息:
实际过程不包括转换为char[]
必然,它实际上是一个"多子串"操作.像3个索引和它们的长度附加.
该StringBuilder
有少数concats的开销太大.
编辑:
由于我要求的一些模糊的方面,让我重新拟定它.
这是发生的事情:
char[]
.char[]
被转换为一个string
.我想做的是合并第2步和第3步,结果是:
string
(并且GC在过程中可以通过正确使用fixed
关键字来保持它的手离开?).需要注意的是,我无法从string []更改输出类型,因为这是一个外部库,项目依赖于它(向后兼容性).