题
我以前问过一个相关的问题,所以我知道它是一个未定义的行为。
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是如何在任何当前或未来的平台上实现的。例如,它可能与某种程度上类似的其他对象共享存储。它可能是将数据放在某些平台上的只读区段中。
不隶属于 StackOverflow