Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 呼叫成员->;功能(本);在析构函数中导致Segfault_C++_Qt_Segmentation Fault_Destructor - Fatal编程技术网

C++ 呼叫成员->;功能(本);在析构函数中导致Segfault

C++ 呼叫成员->;功能(本);在析构函数中导致Segfault,c++,qt,segmentation-fault,destructor,C++,Qt,Segmentation Fault,Destructor,以下是违规代码: class FullPage : public QWidget { Q_OBJECT public: explicit FullPage(const AppData* appdata, QWidget* parent = 0); virtual void addIconWorking(IconWorking* temp); virtual void removeIconWorking(IconWorking* temp); ..

以下是违规代码:

class FullPage : public QWidget
{
    Q_OBJECT
public:
    explicit FullPage(const AppData* appdata, QWidget* parent = 0);
    virtual void     addIconWorking(IconWorking* temp);
    virtual void  removeIconWorking(IconWorking* temp);
    ...
}

class IconWorking : public QLabel
{
    Q_OBJECT
public:
    explicit IconWorking(FullPage* parent = 0);
    virtual ~IconWorking();
    ...
}

IconWorking::IconWorking(FullPage* parent) : QLabel(parent)
{
    ...
    parentPage = parent;
    parentPage->addIconWorking(this);
    ...
}

IconWorking::~IconWorking()
{
    parentPage->removeIconWorking(this); //segfault
    QMessageBox::information(0, "TODO", "Reminder Message");
}
  • 标记的线路在呼叫前出现故障。(断点已命中,但函数中的断点未命中)
  • parentPage永远不会被删除,此时具有非零值
  • 添加/删除图标工作(IconWorking*)不要对对象本身做任何事情;他们只是从QList中添加/删除它。类似于Qt的本机对象系统,只是我想保证只有IconWorking的在那里进行一些特殊处理
我错过了什么


更新: 我在注释中添加了一些测试代码,以查看parentPage是否发生过更改。没有。我正在使用一个新创建的变量,该变量在构造函数中赋值,并在析构函数中签入

SEGFULT消息未指定地址。如果是的话,那就太好了。直接检查指针会给出一个非零值,包括原始测试和添加的测试,因此它们不是null


我还发现,当我添加一些功能时,我在一个完全不相关的位置得到了一个新的segfault,它引用了在程序中以参数形式传递的同一个完整页面实例。

假设在父页面被破坏时调用了
~IconWorking()
,正如亲子关系所表明的那样:

当parentPage对象被销毁时,事情按以下顺序发生:

  • parentPage
    实例上调用
    ~FullPage()
    。在此之后,parentPage不再是有效的FullPage对象
  • 调用
    ~Widget()
    ,留下一个QObject
  • 调用
    ~QObject()
    ,删除IconWorking对象(由于父子关系)
  • 执行
    ~IconWorking()
    ,调用父页面上的FullPage::removeIconWorking(),我假设它访问已在步骤1中销毁的特定于FullPage的成员。(此时,parentPage指向的对象仅为有效的QObject,没有其他内容!)
  • 撞车

  • 要使此方法起作用,~FullPage()必须手动删除IconWorking对象,而不是依赖QObject父子关系。

    好吧,我发现项目的另一部分可能会对该结构感到尴尬,因此我:

    • 使完整页面的QList
      公开
    • 删除了要添加和删除的成员函数
    • 让我直接操纵它,因为这就是所有发生的事情
    不知何故,这似乎修复了析构函数中的segfaults,但我在一些类定义本身上得到了它们。(什么!?!)所以我重建了这个项目,这也被修复了



    所以我猜这个故事的寓意是,如果它做了一些奇怪的事情,尝试一次彻底的重建。一个类中的更改可能需要重新编译另一个类,即使另一个源实际上没有更改,Qt Creator也不一定知道这一点。

    现在看不到任何问题。
    parentPage
    的值仍然有效吗?segfault提到了哪个地址(如0与其他地址)
    removeConworking
    是虚拟的,这表明
    指向无效位置,并且当程序尝试取消引用指针以访问vtable时,会发生segfault。检查parentPage是否不为null。在ctor中打印
    parentPage
    *parentPage
    ,然后再次在dtor中,验证
    parentPage
    未更改且
    *parentPage
    仍然合理。您如何调用析构函数?通过删除其父项或删除
    IconWorking
    ?我想我应该更清楚。有几个完整的页面在整个应用程序关闭之前是不会被销毁的。I与这些父对象一起创建工作,然后在父对象存活期间随意删除,让析构函数负责清理。@AaronD:然后请添加一个回溯以查看在哪种上下文中调用数据或等待一分钟……事实上,我认为您做得对。就是在我关闭应用程序的时候,这完全符合你所描述的。这是正常使用的例外,我只是碰巧测试了一下+1.