2017-09-15 84 views
-7

考虑下面的代码片段:什么是C++字符串的默认容量?

string line; 
line = ""; 
cout << line[400] << endl; //Works, random character 
cout << line[20000] << endl; //Segmentation Fault 

看起来像C++字符串有一个默认的能力,以防止到达边界之外,当不好的事情发生。但我无法找到关于此主题的更多资源。

我在mac环境下编译了clang代码片段。

+5

有标准没有定义默认容量。 – Galik

+8

你遇到的错误不是因为字符串有'默认容量',这是因为你在随机存储器周围。 – pvg

+0

@Galik当你做line.capacity()时,它会返回22,但是肯定会发生更多的事情发生在这里 –

回答

2

那么,标准根本没有给出默认容量。

虽然许多实现都是小型字符串优化(SSO),所以它们具有(相对较小的)最小容量而没有任何额外的分配。

您所遇到的事情与此无关:
未定义的行为

正如名字所说,无论您是否期望,都可能发生任何事情。你的字符串后备存储可能被更多的可寻址内存所包围,但是你的任意读取是否会触及它,这是任意的。

+0

事实上,OP获得的'capacity()'的结果是来自SSO。 https://wandbox.org/permlink/Ii7bNqR6scDRoist – Justin

1

正如评论中所解释的那样,标准中没有定义默认容量,所以对于您的直接问题的答案是“没有一个”。 你看到的结果只是未定义的行为,所以不能得出有用的结论。


然而,尝试回答隐含的潜在的问题(“这是怎么回事?”),当一个页面边界侵犯分割故障通常发生 - 访问“时,无法超越什么应该被分配到变量“,因此这里的容量实际上并不相关。

你可能看到的是line.c_str() + 400仍然在页面上,但是当你进一步去20000字节时,你可能会偏离目标,所以你得到了SigSeg。但是,是的,未定义的行为锤降下来,并把这一切都推测为猜测。

0

还有很多人说过,使用operator[]方法访问std::string超出字符串大小的方法是未定义的行为。当遇到未定义的行为时,程序被允许执行任何操作,直到并包括删除所有文件。 (它不会,但它被允许。)要安全地访问一个字符,可能会或可能不会是字符串的边界之外,使用at代替operator[]

但是,要回答您的原始问题,可以通过在字符串上调用max_size()来确定std::string的最大大小。详情请参阅max_size()

+0

max_size()不是我很感兴趣的,capacity()更相关。 –

相关问题