[英]std:string::substr is exception safe?
我在std::string
使用substr
编写了一些代码。
根据此C ++文档 :
如果pos大于字符串长度,则抛出out_of_range异常。
正如我已经检查过的,如果我使用以下参数执行此功能:
我执行功能: test.substr(0,test.size()-2);
std::string test = {"ABC"}; result: test == "A"
std::string test = {"AB"}; result: test == ""
std::string test = {"A"}; result: test == "A"
std::string test = {""}; result: test == ""
我的结论是:
我的问题:
将其保留为test.substr(0,test.size()-2);
是否安全test.substr(0,test.size()-2);
之前没有检查它的大小?
这是完全安全的。 如果引发异常,它只是第一个参数(除了bad_alloc
耗尽内存,然后还有其他问题)。
第一个参数必须位于[0, size()]
。 由于您使用0
,并且0
始终位于[0, size()]
,因此永远不会引发std::out_of_range
异常。
如果第二个参数大于子字符串的大小,会发生什么,就是您只得到完整的子字符串。 所以test.substr(0,test.size()-2);
对于std::string test = {""}
总是会导致""
因为test.size()-2
是一个非常大的数字(无符号下溢)。
当pos > size()
时,该函数引发异常。在您的示例中,参数pos
始终等于0,那么该函数是安全的。 那就是pos
永远不能大于size()
的值。
考虑到第二个参数的定义如下
basic_string substr(size_type pos = 0, size_type n = npos) const;
^^^^^^^^^^^^^^^^^^
并且函数(C ++ Standard)的行为类似于
2效果:确定要复制的字符串的有效长度rlen为n和size()-pos中的较小者。
对于这个表达
test.size()-2
当您有较大的无符号值时(由于通常的算术转换),当size()
小于2时,它具有无符号整数类型。 例如
#include <iostream>
#include <string>
int main()
{
std::string s;
auto n = s.size() - 2;
std::cout << n << '\n';
return 0;
}
程序输出为
18446744073709551614
因此,该函数选择成员函数size()
。
这两个例子说明了这种情况。
4)std::string test = {"A"}; result: test == "A"
5)std::string test = {""}; result: test == ""
是的,它是安全的,但并非出于您认为是安全的原因。
首先要注意的是: std::string::substr
不是完全异常安全的,如果pos
(即第一个参数)大于size()
,它将抛出异常。
其次, substr
两个参数均为std::string::size_type
类型,默认情况下为无符号整数类型。
因为它是无符号的,所以下溢是定义明确的,因此0 - 2
将导致std::numeric_limits<std::string::size_type>::max() - 1
。
substr()
第二个参数没有上限,因此可以安全地调用substr()
高的值(实际上,默认参数可能是std::numeric_limits<std::string::size_type>::max()
)。
所以,当你调用发生substr(0, negative_value)
是你问“给我从指数串0
至huge_number
”,这大概在所有的情况下将返回整个字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.