1

我遇到了一些代码,其中包含以下示例的几个实例:

std::string str = "This  is my string";
char* ptr = const_cast<char*>(str.c_str());

ptr[5] = 'w';
ptr[6] = 'a';

在这个简化的例子中,有一个 的赋值std::string::c_str(),它返回const char*一个char*使用 的指针const_cast

这似乎按预期工作,并进行了str相应修改。

std::string::c_str()在我本地图书馆的描述如下:

返回指向以 null 结尾的内容的 const 指针。这是内部数据的句柄。不要修改,否则可能会发生可怕的事情

cppreference中,描述包括:

返回指向以空字符结尾的字符数组的指针,该数组的数据与存储在字符串中的数据等效。

...

写入通过访问的字符数组c_str()是未定义的行为。

在标准[string.accessors]中,描述是相似的,并且没有提供关于这个...以空字符结尾的字符数组的信息,其数据与存储在字符串...中的数据等效

而不是澄清问题,这让我更加困惑,什么字符数组?它如何等效?是副本吗?如果是这样,为什么要修改它,还要修改原始字符串?此实现是否已定义?

我想避免更改使用它的所有代码实例的任务,所以我的问题是:

有什么方法可以正确,使用ptr指针修改str字符串是否合法?

4

1 回答 1

6

您引用的参考资料c_str在这个问题上非常清楚:

程序不得修改存储在字符数组中的任何值;否则,行为未定义。

它碰巧起作用的事实并不意味着什么。未定义的行为意味着程序可以根据需要做“正确”的事情。


如果您确实想修改基础数据,您可以使用data()C++17 中提供的非常量重载,它允许您修改除空终止符之外的所有内容:

程序不得将存储在 p + size() 中的值修改为 charT() 以外的任何值;否则,行为未定义。

于 2020-09-07T17:48:07.740 回答