代码之家  ›  专栏  ›  技术社区  ›  suhdonghwi

在C++11之前的标准下使用string::c_str()和data()。

  •  2
  • suhdonghwi  · 技术社区  · 6 年前

    根据 this answer ,的内部缓冲区 std::string 在C++11之前的标准下不能保证是连续的。(尽管几乎所有实现都使用连续内存)

    从技术上讲,这意味着访问n个(n>0?)返回值的元素 string::data() string::c_str() 导致未定义的行为。这是对的吗?

    std::string str = "Hello, World!"
    str.c_str()[1]; // Which is equivalent to *(str.c_str() + 1), therefore UB?
    
    2 回复  |  直到 6 年前
        1
  •  3
  •   Juergen    6 年前

    不,因为C++ 98的规范清楚地说明了你得到的:一个连续的字符数组。

    字符串存储的内部实现不一定反映在方法结果中。如果字符串不是存储在一个部分中,那么方法必须确保您得到了所需的内容。这可能意味着,整个内容被复制到不同的地方。

    这就是为什么你不应该改变你得到的字符串表示。

    您和实现这些方法的人都必须仔细阅读描述您所得到的结果的标准。

        2
  •  0
  •   catnip    6 年前

    str.c_str()[...]; 很好,只要你不跑掉绳子的末端。毕竟,它是一个c字符串,所以你还期望什么呢?

    至于 str.data() , cppreference 有话要说:

    const CharT* data() const 返回用作字符存储的基础数组的指针。指针是这样的:范围[data();data()+size())是有效的,其中的值对应于存储在字符串中的值。

    现在我不知道这是否是完全可信的,但是cppreference并不限定该语句适用于标准的任何特定版本。但是,也许,应该这样。