引用/指针的无效到底是什么?

时间:2018-08-08 13:55:16

标签: c++ pointers reference language-lawyer invalidation

我在标准中找不到关于指针/引用无效的任何定义。我问是因为我刚刚发现C ++ 11禁止对字符串进行写时复制(COW)。据我了解,如果应用了COW,则在执行以下命令后,p仍然是有效的指针,r仍然是有效的引用:

std::string s("abc");
std::string s2(s);
char * p = &(s2[0]);
char & r = s2[0];
s2[1] = "B";

只是他们不再指向/引用s2的第一个字符,而只是指向s的第一个字符。

在C ++ 11标准中,据说非常数std::basic_string::operator[]不会使指向字符串元素的指针/引用(以及迭代器)无效。

哪个规则说,如果实施了COW,则上面显示的示例实际上会使pr无效?

2 个答案:

答案 0 :(得分:6)

标准中没有“无效”的定义,因为该术语是从英语继承的。这意味着英语的含义:无效的引用/指针不再有效。无法使用。

但是,在某些地方明确指出了此约束。例如,将指针左值转换为右值时(在表达式求值期间发生):

  

[conv.lval/2]否则,如果glvalue引用的对象包含无效的指针值(3.7.4.2、3.7.4.3),则该行为是实现定义的

我现在找不到引用的用语,但总的来说,您不能使用对不再存在的引用。

答案 1 :(得分:0)

例如:

std::string * p_s(new ::std::string("abc"));
std::string s2(*p_s); // shares buffer with p_s
char const & ch1(static_cast<::std::string const &>(*p_s)[0]);
char const & ch2(static_cast<::std::string const &>(s2)[0]); // same as ch1
// CoW, ch2 becomes invalid, but is backed by p_s buffer
char & ch(static_cast<::std::string &>(s2)[0]); // backed by new buffer
// both ch1 and ch2 become invalid
delete p_s;