C ++:访问空字符串的元素时,没有错误,为什么?

时间:2017-01-08 13:05:16

标签: c++ string

#include <iostream>
#include <string>
using std::string;
int main(){
    string s;
    std::cout << "size:" << s.size() << " "
                      << "capacity:" << s.capacity() << std::endl;
    std::cout << s[3] << std::endl;
    return 0;
}

我定义了一个名为 s 的空字符串对象。 s.size() s.capacity(),但访问元素时 s [3] < / strong>,没有段错,为什么?

4 个答案:

答案 0 :(得分:5)

撇开(正如其他人所解释的)这是UB和(在学术上说)任何事情都可能发生的事实,在这个特定情况下你没有得到分段错误的具体原因是操作系统没有检测分配对象之外的所有内存访问 - 它只检测无效内存访问所以错误,它是完全是0x0还是完全是虚拟内存的另一页,你的进程没有提供。这是&#34;自动&#34;的唯一级别。存在的内存错误检测。

除此之外,您的计算机必须检查每个内存访问并将其与免费存储中分配的块映射进行比较(这非常慢;您可以在调试期间使用电栅栏等工具执行此操作 valgrind ,或者你必须自己添加索引检查(例如使用.at()而不是[])。

C ++在某种程度上是一种安全的语言,但仍然有很多功能让人感觉从C继承,在那里你有责任知道自己在做什么,并且不能依靠你的电脑告诉你你做错了什么。

答案 1 :(得分:2)

当你访问一个你不拥有的内存时,它不会发生段错误,可以发生。

答案 2 :(得分:1)

你正在调用一种称为未定义行为的东西。它可能崩溃,它什么也不做,它可以做你想要的。没有任何保证。这种行为完全是“未定义的”。

答案 3 :(得分:1)

因为C ++中的许多错误没有定义的效果,而是导致未定义的行为。将不可能的索引传递给std::string&#39; operator[]就是这种错误的一个例子。任何事情都可能发生。

这是因为要求编译器创建在运行时执行各种错误检查的程序会严重降低C ++在错误检查开销不可接受的使用场景中的可用性。通常,如果你想在C ++中像这样进行运行时错误检查,那么你必须询问(并支付费用)。

一种相当简单的方法是使用at成员函数,这是非法字符串索引抛出异常所必需的。但你将如何处理&#34;像这样的例外情况,除了catch中的一个丑陋的main,它会记录错误并退出吗?

非法字符串索引应该被视为 bug ,必须修复,而不是&#34;处理&#34;在运行时。幸运的是,有一些方法可以告诉编译器在运行时添加错误的operator[]检测。这里有更多信息:

请注意,只有size与确定访问元素是否为未定义行为相关。 capacity不是。