C++ 部分毁坏的物体?

C++ 部分毁坏的物体?,c++,scope,destructor,C++,Scope,Destructor,我试图理解在这种简单的情况下破坏是如何运作的: class A { public: A(int i) { this->b = i; } void p() { std::cout << a << " " << b << std::endl;} private: string a = "42"; int b = 0; }; int main() { A* ap = nullptr; while (

我试图理解在这种简单的情况下破坏是如何运作的:

class A {
public:
    A(int i) { this->b = i; }
    void p() { std::cout << a << " " << b << std::endl;}
private:
    string a = "42";
    int b = 0;
};

int main() {
    A* ap = nullptr;
    while (true) {
         A k(24);
         ap = &k;
         k.p();
         break;
    } // A out of scope, I expect any pointer to A to be invalidated.
ap->p(); // still callable, b has been freed but not a!?
}
A类{
公众:
A(inti){this->b=i;}

void p(){std::coutC++不是一种固有的引用计数语言,因此当对象被破坏时,指针不会以任何方式直接失效。您导致了未定义的行为,任何事情都可能发生。编译器不需要诊断此问题

ap为什么指向部分有效的对象

ap没有指向部分有效的对象。这是UB。代码可以工作,因为即使k超出范围,内存也不会改变

这里发生的情况是,当k超出范围时,空闲堆栈内存(下一个堆栈对象将被放置的位置)的内存偏移量发生变化,因此k(k“was”所在的内存)保留在空闲堆栈空间中。在堆栈上放置另一个对象(在循环之后)可能会使ap中地址处的内存无效


UB表示任何事情都可能发生(在本例中,“anything”表示ap指向的内存仍然指向A::p函数的地址。

您始终可以调用
ap->p()
,但如果您不能保证
ap
指向属于
a类
实例的有效内存位置,则您的程序将具有未定义的行为


未定义的行为意味着您的程序可以执行任何操作,包括崩溃、不执行任何操作或执行任何其他操作。

未定义的行为正如其名称所示是不可预测和不可靠的。不要假设观察到的行为是已定义的行为。