string :: c_str()是否允许在堆上分配任何东西?

时间:2010-09-29 15:23:09

标签: c++ string

如果我需要确保不会分配任何内容,我需要从char中获取NUL终止的std::string数组,使用c_str是否安全这样做?例如,如果我在析构函数中并且我想将一些数据从string复制到预先分配的固定大小的缓冲区中,我可以使用c_str并确保它不会抛出什么?

4 个答案:

答案 0 :(得分:7)

标准规定调用c_str()可能会使引用,指针和指向string元素的引用无效,这意味着允许实际位置(21.3 / 5“类模板basic_string”)。

您可能只想调用string::copy()来获取副本(如果需要,您需要自己添加空终结符)。

答案 1 :(得分:6)

不,标准没有这样的保证。 C ++标准中唯一的保证是返回的值指向char数组,其内容与std::string相同,加上一个nul-terminator。

因此,符合标准的实现以某种方式存储其内部表示而不是C字符串,并在您调用c_str时动态分配C字符串,尽管我是相当肯定没有广泛使用的STL实现实际上是这样做的。

现在,关于C ++ 0x,我听说过(虽然我现在因为找不到这方面的文档而感到茫然),但其中一个变化是要求std::string在连续存储上运行(std::vector已经存在类似的要求)。因此,在这种情况下,您可以从&str[0]&str[0]+str.length()-1访问范围,就像它是没有nul-terminator的C字符串一样。

答案 2 :(得分:2)

标准对此保持沉默:

21.3.6 [lib.strings.ops]

  

const charT * c_str()const; 1   返回:指向初始的指针   长度大小为()+的数组元素   1的第一个size()元素相等   相应的元素   字符串由* this和其控制   最后一个元素是一个空字符   由charT()指定。

     

2要求:程序不得   改变存储在中的任何值   阵列。程序也不应该对待   返回值作为有效指针   任何后续调用a后的值   类的非const成员函数   basic_string指定相同的   这是对象。

可以。也就是说,我从来没有见过任何实现。

如果您担心这一点,可以考虑使用vector<char>代替string,并执行以下操作:

vector<char> chars;
// ...
char* my_str = &chars[0];

这里的诀窍是知道什么时候&amp;如何处理'\0' - 终止字符串的需要。

答案 3 :(得分:1)

标准除了明确表示当你调用c_str时字符串可以分配内存。特别是,它说(§21.3/ 5):

  

引用basic_string序列元素的引用,指针和迭代器可能会被该basic_string对象的以下用法无效:
  [...]
   - 调用data()和c_str()成员函数。

它使指针,引用和迭代器的权限无效具体,以允许实现在您调用c_str时重新分配用于存储字符串的内存。