为什么可以将std::unique_ptr<A>* u1访问为u1[1000],而且还能正常工作[重复]?

问题描述 投票:0回答:1

对不起,我的标题很傻,想不出应该怎么写。我在玩unique_ptr,创建了unique_ptr的指针(我知道我不应该创建unique_ptr的指针,我只是在玩看看发生了什么)。

class A
{
  public:
    A() {std::cout<<"A const\n";}
    ~A() {std::cout<<"~A dest\n";}
    void fun()  {std::cout<<"A fun\n";}

};

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

c++ arrays c++11 pointers unique-ptr
1个回答
3
投票

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

在实际操作中,你执行 A::fun() 无效的 this 指针,而且由于 A::fun() 不引用成员变量或虚拟函数,你就可以逍遥法外。 这可能是个坏消息,而不是好消息,因为你那里有一个等待发生的错误。


1
投票

为什么这段代码可以执行?

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

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

我希望输出是崩溃

当行为未定义时,你不能依靠程序按你期望的方式行事。


int* t= new int(10); t[1] = 1000; 永远不会成功。这里我还期望

你怎么知道它 "从不工作"?你是否观察过每一个程序的执行情况,在每一个存在的系统上,用过去和未来的每一个编译器的每一个版本进行编译,有或没有编译器所提供的各种选项?我怀疑你没有。即使我们假设你有,也不能保证它的行为符合你的期望。

这个程序 "永远不会工作",就像问题中的程序 "永远不会工作 "一样。行为是未定义的,任何事情都有可能发生。它可能会。

  • 总是崩溃
  • 永不崩溃
  • 有时崩溃
  • 你运行时崩溃,但别人运行时不会崩溃
  • 总是有特定的输出
  • 从来没有这种输出
  • 有时有这种输出
  • 始终没有输出
  • 从来没有任何产出
  • ...

这个列表是无限的。

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

在C++中是没有答案的。你必须阅读编译器生成的汇编语言程序,然后问 "为什么这个汇编程序会崩溃",那么答案可能在你的CPU和操作系统的手册中找到。

© www.soinside.com 2019 - 2024. All rights reserved.