我以前问过一个相关的问题,所以我知道它是一个未定义的行为。

将const char*返回到char*,然后更改数据

string _str = "SDFDFSD";
char* pStr = (char*)_str.data();
for (int i = 0; i < iSize; i++)
    pStr[i] = ::tolower(pStr[i]);

我和我的一位同事讨论了这个问题。他告诉我,除非我改变数据的长度,否则在这种情况下不会造成任何问题。如果我改变数据,但保持长度不变,它将永远不会产生任何问题,因为没有办法 std::string 来检测数据已被更改。它也不会导致任何内部不一致 _str.真的是这样吗?

有帮助吗?

解决方案

未定义的行为 恐怕被谴责得太多了,提到鼻守护进程似乎让大多数人相信它比其他任何东西都更神秘。

看来,你的同事已经如此脱敏,为了说服你因此需要把他的问题的具体证据。幸运的是,如果你手头有gcc,它可以完成:

#include <iostream>
#include <string>

int main() {
    std::string const UPPER = "HELLO, WORLD!";
    std::cout << "UPPER: " << UPPER << "\n";

    std::string lower = UPPER;
    for (char* begin = const_cast<char*>(lower.data()),
         * end = begin + lower.size();
         begin != end;
         ++begin)
    {
        *begin = std::tolower(*begin);
    }
    std::cout << "lower: " << lower << "\n";
    std::cout << "UPPER: " << UPPER << "\n";
    return 0;
}

如果使用gcc, 这是你得到的:

UPPER: HELLO, WORLD!
lower: hello, world!
UPPER: hello, world!   // What the hell ? UPPER was const !!!

为啥?因为gcc历史上用 书面副本, ,自从你 被骗了 它没有检测到写入,因此底层存储阵列被共享。

注:是的,这与C++11不一致,我希望我有机会在C++11中工作。

其他提示

根据 数据() 文件:

修改通过数据访问的字符数组是未定义的行为。

所以你的同事错了,没有窍门,它是未定义的行为。会发生什么是具体的实现。

坏主意!您无法确定string是如何在任何当前或未来的平台上实现的。例如,它可能与某种程度上类似的其他对象共享存储。它可能是将数据放在某些平台上的只读区段中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top