更改数据忽略const限定符

时间:2014-06-04 05:35:15

标签: c++ pointers const

我之前已经问了一个相关的问题,所以我知道这是一个未定义的行为。

returning const char* to char* and then changing the data

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

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

3 个答案:

答案 0 :(得分:2)

根据data()文档:

  

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

所以你的同事错了,没有诀窍,这是未定义的行为。具体实现的是什么。

答案 1 :(得分:2)

未定义的行为已被谴责过多,我担心,对鼻腔守护进程的引用似乎使大多数人相信它比其他任何东西更神秘。

你的同事似乎已经脱敏了,为了说服你,因此需要给他带来问题的具体证据。幸运的是,如果你手头有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,here is what you get

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

为什么?因为gcc历来使用 Copy On Write ,并且由于你被欺骗它没有检测到写入,因此底层存储阵列是共享的。

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

答案 2 :(得分:1)

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