【问题标题】:Partially destroyed object?部分破坏的对象?
【发布时间】:2014-02-28 16:38:57
【问题描述】:

我试图了解在这个简单的情况下破坏是如何工作的:

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!?
}

ap 怎么会指向一个部分有效的对象?我做错了什么并且不理解?请准确解释,因为我是 C++ 新手。谢谢!

编辑:假设我在 ~A(); 中调用 p();这样做安全吗?

【问题讨论】:

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

标签: c++ scope destructor


【解决方案1】:

ap 怎么会指向一个部分有效的对象?

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

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

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

【讨论】:

    【解决方案2】:

    C++ 不是一种固有的引用计数语言,因此当对象被销毁时,指针不会以任何方式直接失效。您正在诱导未定义的行为,并且任何事情都可能发生。诊断此问题不需要编译器。

    【讨论】:

      【解决方案3】:

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

      未定义的行为意味着您的程序可以做任何事情,包括崩溃、什么都不做或做任何其他事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-25
        • 1970-01-01
        • 1970-01-01
        • 2018-11-19
        • 2010-11-13
        • 1970-01-01
        相关资源
        最近更新 更多