Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将std::string附加到自身是否安全?_C++_Stl - Fatal编程技术网

C++ 将std::string附加到自身是否安全?

C++ 将std::string附加到自身是否安全?,c++,stl,C++,Stl,考虑到这样的代码: std::string str = "abcdef"; const size_t num = 50; const size_t baselen = str.length(); while (str.length() < num) str.append(str, 0, baselen); std::string str=“abcdef”; 常量大小\u t num=50; 常量大小=长度(); while(str.length()

考虑到这样的代码:

std::string str = "abcdef";
const size_t num = 50;

const size_t baselen = str.length();
while (str.length() < num)
    str.append(str, 0, baselen);
std::string str=“abcdef”;
常量大小\u t num=50;
常量大小=长度();
while(str.length()
像这样对自身调用
std::basic\u string::append()
安全吗?源内存不能在复制操作之前通过放大而失效吗

我在标准中找不到与该方法相关的任何内容。它说上面的内容相当于
str.append(str.data(),baselen)
,我认为这可能并不完全安全,除非在
append(const char*,size\u t)
中再次检测到这种情况


我检查了一些实现,它们看起来是安全的,但我的问题是,这种行为是否有保证。例如,“根据§21.4.6.2/§21.4.6.3,表示它不是用于
std::vector

函数[
basic_string&append(const charT*s,size_type n);
]将*this控制的字符串替换为长度为size()+n的字符串,其第一个size()元素是*this控制的原始字符串的副本,其余元素是*this的初始n个元素的副本

注:这适用于每个
append
调用,因为每个
append
都可以按照标准(§21.4.6.2/§21.4.6.3)定义的
append(const charT*,size_type)
实现

所以基本上,
append
复制
str
(我们称之为副本
strtemp
),将
str2
n
字符追加到
strtemp
,然后用
strtemp
替换
str

对于
str2
str
的情况,没有任何变化,因为在分配临时副本时,而不是之前,字符串会放大

尽管标准中没有明确规定,但通过
std::basic_string::append
的定义可以保证(如果实现与标准中的规定完全一致)

因此,这不是未定义的行为。

这很复杂

有一件事是可以肯定的。如果使用迭代器:

std::string str = "abcdef";
str.append(str.begin(), str.end());
那你就保证安全了。是的,真的。为什么?因为规范规定迭代器函数的行为等同于调用
append(基本字符串(第一个,最后一个))
。这显然会创建字符串的临时副本。因此,如果需要将字符串插入到自身中,则可以保证能够使用迭代器形式来完成

诚然,实现不必实际复制它。但他们确实需要尊重标准规定的行为。只有当迭代器范围在自身内部时,实现才能选择创建副本,但实现仍需要进行检查

所有其他形式的
append
被定义为等同于调用
append(const charT*s,size\t len)
。也就是说,上面对append的调用相当于执行
append(str.data(),str.size())
。那么,如果
s
位于
*此
的内部,该标准会说明什么

什么都没有

s
的唯一要求是:

s
指向
图表的至少
n
元素的数组


由于它没有明确禁止
s
指向
*此
,因此必须允许。如果迭代器版本允许自赋值,但指针和大小版本不允许,这也会非常奇怪。

应该是这样,但我找不到任何方法<代码>str+=str
是合法的,归结起来是同一件事,所以我想它是好的。@NathanOliver:事实上,不把它定为非法是有充分理由的。对于字符串,将相同的字符串附加到其自身或字符串的子集是合理的。使用
向量
,可能性要小得多。@Nicolas我明白了。我只是没有找到标准来支持我的论点。看起来像是Rakete1111。我明白了,谢谢-我应该读一下
append(const charT*,size\u type)
的定义。