首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >std::unique_ptr、pimpl和对象生存期

std::unique_ptr、pimpl和对象生存期
EN

Stack Overflow用户
提问于 2022-01-24 10:23:06
回答 1查看 102关注 0票数 2

下面的示例在Linux上编译gcc 11 (GNU ),在FreeBSD上编译clang 12 (Clang )。在Linux上,它运行并打印值1和2。在FreeBSD上,它打印值1,然后使用SEGV崩溃。我不认为完全理解对象的生存期--因此,整个过程可能是UB,运行时行为可能与此无关。我确实知道,这两个STL之间的implementation of std::unique_ptr有一个重要的区别: Clang在析构函数开始时重置std::unique_ptrnullptr的内部指针,而GNU只保留指针。

代码语言:javascript
复制
#include <iostream>
#include <memory>

struct C {
    struct Private {
        C* m_owner;
        int m_x;
        Private(C* owner) : m_owner(owner), m_x(0) {}
        ~Private() { m_owner->cleanup(); }
        void cleanup() { std::cout << "Private x=" << ++m_x << '\n'; }
    };
    
    std::unique_ptr<Private> d;
    C() { d = std::make_unique<Private>(this); }
    ~C() = default;
    void cleanup() { d->cleanup(); }
};

int main(int argc, char **argv)
{
    C c;
    c.cleanup(); // For display purposes, print 1
    return 0; // Destructors called, print 2
}

FreeBSD上的输出:

代码语言:javascript
复制
Private x=1
Segmentation fault (core dumped)

还有一段回溯:

代码语言:javascript
复制
* thread #1, name = 'a.out', stop reason = signal SIGSEGV: invalid address (fault address: 0x8)
    frame #0: 0x00000000002032b4 a.out`C::Private::cleanup() + 52
a.out`C::Private::cleanup:
->  0x2032b4 <+52>: movl   0x8(%rax), %esi

我认为这可能是UB的原因是:

  • at return 0c的生命即将结束,
  • ,破坏者~C(),运行。一旦完成了析构函数的主体(默认),对象的生存期就结束了,并且使用该对象的是UB。
  • 现在是子对象的析构函数(成员对象?)
  • 析构函数~std::unique_ptr<Private>正在运行。它为所保存的对象运行析构函数。析构函数
  • ~Private()使用指向已不存在的对象m_owner的指针来调用成员函数.

如果对对象生命周期的理解是正确的,我将希望得到一个答案。

如果不是UB,那么就有一个单独的实现质量问题(或者我应该在调用方法之前检查d-指针,但是对于pimpl来说,这似乎有点不正常;然后我们得到一个STL实现所需要的if(d)d->cleanup(),在另一个STL实现中这是一个无用的检查)。

为了提出一个问题:在销毁对象m_owner->cleanup()期间,该代码是否在语句c (第9行)中显示UB?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-24 10:33:37

是的,m_owner引用的对象的生存期已经结束,当调用m_owner->cleanup();时,它的析构函数调用已经完成。因此,呼叫是UB。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70832270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档