为什么可以将 std::unique_ptr* u1 <A>作为 u1[1000] 访问并且它仍然有效

Why it's possible to access std::unique_ptr<A>* u1 as u1[1000] and it still works

本文关键字:u1 访问 1000 有效 作为 gt ptr unique 为什么 lt std      更新时间:2023-10-16

对不起,愚蠢的标题,想不出应该如何。 我正在玩unique_ptr,创建了指向unique_ptr的指针(我知道我不应该创建指向unique_ptr的指针,我只是在玩看看发生了什么(

class A
{
public:
A() {std::cout<<"A constn";}
~A() {std::cout<<"~A destn";}
void fun()  {std::cout<<"A funn";}
};
int main()
{
std::unique_ptr<A>* u1 = new std::unique_ptr<A>(new A);
u1[1000]->fun();
delete u1;
return 0;
}

我预计输出会崩溃,但它就像我使用 u1[0] 时一样工作。我完全不知道为什么,我完全希望它崩溃。

A const
A fun
~A dest

为什么执行此代码? 它适用于 g++ 以及在线 c++ shell http://cpp.sh/

从技术上讲,u1[1000]->fun();表现出未定义的行为,因此"任何事情都可能发生"。

实际上,您使用无效的this指针执行A::fun(),并且由于A::fun()不引用任何成员变量或虚函数,因此您可以侥幸逃脱。 这可能是个坏消息,而不是好消息,因为你有一个错误正在等待发生。

这段代码是如何执行的?

因为程序的行为是未定义的。

不能保证程序会崩溃,也不能保证它不会崩溃。对行为没有任何保证。

我预计输出会崩溃

当行为未定义时,您不能依赖程序按照预期的方式运行。


int* t= new int(10(; t[1] = 1000;从不工作。在这里我也期待

你怎么知道它"永远不起作用"?您是否观察过每个程序的每次执行,这些程序的每次执行都在过去和将来,无论编译器必须提供还是没有编译器必须提供的所有各种选项,在现有的每个系统上?我怀疑你没有。即使我们假设你有,仍然不能保证它的行为符合你的预期。

该程序"从不工作",就像问题中的程序"从不工作"一样。行为是不确定的,任何事情都可能发生。它可能:

  • 总是崩溃
  • 永不崩溃
  • 有时会崩溃
  • 运行时崩溃
  • ,但其他人运行时不会崩溃
  • 始终具有特定的输出
  • 永远没有那个输出
  • 有时有那个输出
  • 始终没有输出
  • 从不有任何输出

这个列表是无限的。

我认为在大多数情况下,即使是UB也有一些解释,就像在我的情况下为什么它不会崩溃一样

C++内部没有答案。相反,您必须阅读编译器生成的汇编语言程序并询问"为什么此汇编程序崩溃",然后答案可以在您的CPU和操作系统的手册中找到。