c++ - 复制和修改 std::strings 时无法解释的差异

标签 c++ string c++11 copy-constructor

在下面的代码中,“情况 1” 在所有情况下都按预期工作 编译器经过测试,但是“情况 2” 似乎表现不同 基于所使用的编译器。

例如,MSVC 让 sit1 和 sit2 产生相同的结果,但是 使用 gcc/clang 和 libstdc++ 时,修改发生在 原始字符串和它的拷贝 (有点像 COW 字符串) 即使 我正在使用 C++11 开关进行构建。

#include <iostream>
#include <string>

int main() {

   // situation 1
   {
      std::string x0 = "12345678";
      std::string x1 = x0;

      char* ptr = &x0[0] + 3;

      (*ptr) = ' ';

      std::cout << "1. x0: " << x0 << "\n";
      std::cout << "1. x1: " << x1 << "\n";

      if ((&x0[0]) == x0.data()) std::cout << "1. ptrs are equal\n";

   }

   // situation 2
   {
      std::string x0 = "12345678";
      std::string x1 = x0;

      char* ptr = const_cast<char*>(x0.data() + 3);

      (*ptr) = ' ';

      std::cout << "2. x0: " << x0 << "\n";
      std::cout << "2. x1: " << x1 << "\n";

      if ((&x0[0]) == x0.data()) std::cout << "2. ptrs are equal\n";
   }

   return 0;
}

海湾合作委员会 (6.1)

1. x0: 123 5678
1. x1: 12345678
1. ptrs are equal
2. x0: 123 5678
2. x1: 123 5678
2. ptrs are equal

MSVC (2015)

1. x0: 123 5678
1. x1: 12345678
1. ptrs are equal
2. x0: 123 5678
2. x1: 12345678
2. ptrs are equal

鉴于 &x0[0] 和 .data() 返回相同的地址,各种编译器之间的行为差​​异是否有任何原因?

最佳答案

情况 2 导致未定义的行为:

char* ptr = const_cast<char*>(x0.data() + 3);

(*ptr) = 'Z';

根据 std::basic_string::data (C++14 [string.accessors]/3) 的规范:

Requires: The program shall not alter any of the values stored in the character array.

换句话说,您不能丢弃 const 并通过 data()c_str()< 返回的指针修改字符串 .

关于c++ - 复制和修改 std::strings 时无法解释的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38985345/

相关文章:

c++ - 了解函数指针和引用

c++ - 如何计算 TinyXml 中的元素?

c++ - 开发 ActiveX 控件

c++ - QTimer - 重复计时器

c++ - 将指针设置为空

c++ - 运行 .exe 文件时出现 std::logic 错误

C#:将文本文件内容与字符串变量进行比较

java - 作为字符串一部分的新行字符

c++ - 用户提供的 terminate() 函数必须是线程安全的吗?

c++ - 包含在 std::regex 搜索中,使用 std::regex_token_iterator 从 std::sub_match 中排除